/*
 * Modest Maps JS v0.9.0
 * http://modestmaps.com/
 *
 * Copyright (c) 2010 Stamen Design, All Rights Reserved.
 *
 * Open source under the BSD License.
 * http://creativecommons.org/licenses/BSD/
 *
 * Versioned using Semantic Versioning.
 * See http://semver.org/ for details.
 * 
 */
if(!com){var com={};if(!com.modestmaps){com.modestmaps={}}}(function(a){a.extend=function(d,b){for(var c in b.prototype){if(typeof d.prototype[c]=="undefined"){d.prototype[c]=b.prototype[c]}}return d};a.cancelEvent=function(b){b.cancelBubble=true;b.cancel=true;b.returnValue=false;if(b.stopPropagation){b.stopPropagation()}if(b.preventDefault){b.preventDefault()}return false};a.addEvent=function(d,c,b){if(d.attachEvent){d["e"+c+b]=b;d[c+b]=function(){d["e"+c+b](window.event)};d.attachEvent("on"+c,d[c+b])}else{d.addEventListener(c,b,false);if(c=="mousewheel"){d.addEventListener("DOMMouseScroll",b,false)}}};a.removeEvent=function(d,c,b){if(d.detachEvent){d.detachEvent("on"+c,d[c+b]);d[c+b]=null}else{d.removeEventListener(c,b,false);if(c=="mousewheel"){d.removeEventListener("DOMMouseScroll",b,false)}}};a.getStyle=function(c,b){if(c.currentStyle){var d=c.currentStyle[b]}else{if(window.getComputedStyle){var d=document.defaultView.getComputedStyle(c,null).getPropertyValue(b)}}return d};a.Point=function(b,c){this.x=parseFloat(b);this.y=parseFloat(c)};a.Point.prototype={x:0,y:0,toString:function(){return"("+this.x.toFixed(3)+", "+this.y.toFixed(3)+")"}};a.Coordinate=function(d,b,c){this.row=d;this.column=b;this.zoom=c};a.Coordinate.prototype={row:0,column:0,zoom:0,toString:function(){return"("+this.row.toFixed(3)+", "+this.column.toFixed(3)+" @"+this.zoom.toFixed(3)+")"},toKey:function(){var e=Math.floor(this.row);var d=Math.floor(this.column);var f=Math.floor(this.zoom);e=e-d;e=e-f;e=e^(f>>>13);d=d-f;d=d-e;d=d^(e<<8);f=f-e;f=f-d;f=f^(d>>>13);e=e-d;e=e-f;e=e^(f>>>12);d=d-f;d=d-e;d=d^(e<<16);f=f-e;f=f-d;f=f^(d>>>5);e=e-d;e=e-f;e=e^(f>>>3);d=d-f;d=d-e;d=d^(e<<10);f=f-e;f=f-d;f=f^(d>>>15);return f},copy:function(){return new a.Coordinate(this.row,this.column,this.zoom)},container:function(){return new a.Coordinate(Math.floor(this.row),Math.floor(this.column),Math.floor(this.zoom))},zoomTo:function(b){var c=Math.pow(2,b-this.zoom);return new a.Coordinate(this.row*c,this.column*c,b)},zoomBy:function(c){var b=Math.pow(2,c);return new a.Coordinate(this.row*b,this.column*b,this.zoom+c)},up:function(b){if(b===undefined){b=1}return new a.Coordinate(this.row-b,this.column,this.zoom)},right:function(b){if(b===undefined){b=1}return new a.Coordinate(this.row,this.column+b,this.zoom)},down:function(b){if(b===undefined){b=1}return new a.Coordinate(this.row+b,this.column,this.zoom)},left:function(b){if(b===undefined){b=1}return new a.Coordinate(this.row,this.column-b,this.zoom)}};a.Location=function(b,c){this.lat=parseFloat(b);this.lon=parseFloat(c)};a.Location.prototype={lat:0,lon:0,toString:function(){return"("+this.lat.toFixed(3)+", "+this.lon.toFixed(3)+")"}};a.Transformation=function(d,f,b,c,e,g){this.ax=d;this.bx=f;this.cx=b;this.ay=c;this.by=e;this.cy=g};a.Transformation.prototype={ax:0,bx:0,cx:0,ay:0,by:0,cy:0,transform:function(b){return new a.Point(this.ax*b.x+this.bx*b.y+this.cx,this.ay*b.x+this.by*b.y+this.cy)},untransform:function(b){return new a.Point((b.x*this.by-b.y*this.bx-this.cx*this.by+this.cy*this.bx)/(this.ax*this.by-this.ay*this.bx),(b.x*this.ay-b.y*this.ax-this.cx*this.ay+this.cy*this.ax)/(this.bx*this.ay-this.by*this.ax))}};a.deriveTransformation=function(l,k,f,e,b,o,h,g,d,c,n,m){var j=a.linearSolution(l,k,f,b,o,h,d,c,n);var i=a.linearSolution(l,k,e,b,o,g,d,c,m);return new a.Transformation(j[0],j[1],j[2],i[0],i[1],i[2])};a.linearSolution=function(f,o,i,e,n,h,d,m,g){f=parseFloat(f);o=parseFloat(o);i=parseFloat(i);e=parseFloat(e);n=parseFloat(n);h=parseFloat(h);d=parseFloat(d);m=parseFloat(m);g=parseFloat(g);var l=(((h-g)*(o-n))-((i-h)*(n-m)))/(((e-d)*(o-n))-((f-e)*(n-m)));var k=(((h-g)*(f-e))-((i-h)*(e-d)))/(((n-m)*(f-e))-((o-n)*(e-d)));var j=i-(f*l)-(o*k);return[l,k,j]};a.Projection=function(c,b){if(!b){b=new a.Transformation(1,0,0,0,1,0)}this.zoom=c;this.transformation=b};a.Projection.prototype={zoom:0,transformation:null,rawProject:function(b){alert("Abstract method not implemented by subclass.")},rawUnproject:function(b){alert("Abstract method not implemented by subclass.")},project:function(b){b=this.rawProject(b);if(this.transformation){b=this.transformation.transform(b)}return b},unproject:function(b){if(this.transformation){b=this.transformation.untransform(b)}b=this.rawUnproject(b);return b},locationCoordinate:function(c){var b=new a.Point(Math.PI*c.lon/180,Math.PI*c.lat/180);b=this.project(b);return new a.Coordinate(b.y,b.x,this.zoom)},coordinateLocation:function(c){c=c.zoomTo(this.zoom);var b=new a.Point(c.column,c.row);b=this.unproject(b);return new a.Location(180*b.y/Math.PI,180*b.x/Math.PI)}};a.LinearProjection=function(c,b){a.Projection.call(this,c,b)};a.LinearProjection.prototype={rawProject:function(b){return new a.Point(b.x,b.y)},rawUnproject:function(b){return new a.Point(b.x,b.y)}};a.extend(a.LinearProjection,a.Projection);a.MercatorProjection=function(c,b){a.Projection.call(this,c,b)};a.MercatorProjection.prototype={rawProject:function(b){return new a.Point(b.x,Math.log(Math.tan(0.25*Math.PI+0.5*b.y)))},rawUnproject:function(b){return new a.Point(b.x,2*Math.atan(Math.pow(Math.E,b.y))-0.5*Math.PI)}};a.extend(a.MercatorProjection,a.Projection);a.MapProvider=function(b){if(b){this.getTileUrl=b}};a.MapProvider.prototype={projection:new a.MercatorProjection(26,new a.Transformation(10680707.79,0,33554431.85,0,-10680708.9,33554430.57)),tileWidth:256,tileHeight:256,getTileUrl:function(b){alert("Abstract method not implemented by subclass.")},locationCoordinate:function(b){return this.projection.locationCoordinate(b)},coordinateLocation:function(b){return this.projection.coordinateLocation(b)},sourceCoordinate:function(d){var b=Math.pow(2,d.zoom);if(d.row>=0&&d.row<b){var c=d.column%b;while(c<0){c+=b}return new a.Coordinate(d.row,c,d.zoom)}return null}};a.TemplatedMapProvider=function(c,b){a.MapProvider.call(this,function(f){f=this.sourceCoordinate(f);if(!f){return null}var d=c;if(b&&b.length&&d.indexOf("{S}")>=0){var e=parseInt(f.zoom+f.row+f.column)%b.length;d=d.replace("{S}",b[e])}return d.replace("{Z}",f.zoom.toFixed(0)).replace("{X}",f.column.toFixed(0)).replace("{Y}",f.row.toFixed(0))})};a.extend(a.TemplatedMapProvider,a.MapProvider);a.MouseHandler=function(b){if(b!==undefined){this.init(b)}};a.MouseHandler.prototype={init:function(b){this.map=b;a.addEvent(b.parent,"dblclick",this.getDoubleClick());a.addEvent(b.parent,"mousedown",this.getMouseDown());a.addEvent(b.parent,"mousewheel",this.getMouseWheel())},mouseDownHandler:null,getMouseDown:function(){if(!this.mouseDownHandler){var b=this;this.mouseDownHandler=function(c){a.addEvent(document,"mouseup",b.getMouseUp());a.addEvent(document,"mousemove",b.getMouseMove());b.prevMouse=new a.Point(c.clientX,c.clientY);b.map.parent.style.cursor="move";return a.cancelEvent(c)}}return this.mouseDownHandler},mouseMoveHandler:null,getMouseMove:function(){if(!this.mouseMoveHandler){var b=this;this.mouseMoveHandler=function(c){if(b.prevMouse){b.map.panBy(c.clientX-b.prevMouse.x,c.clientY-b.prevMouse.y);b.prevMouse.x=c.clientX;b.prevMouse.y=c.clientY}return a.cancelEvent(c)}}return this.mouseMoveHandler},mouseUpHandler:null,getMouseUp:function(){if(!this.mouseUpHandler){var b=this;this.mouseUpHandler=function(c){a.removeEvent(document,"mouseup",b.getMouseUp());a.removeEvent(document,"mousemove",b.getMouseMove());b.prevMouse=null;b.map.parent.style.cursor="";return a.cancelEvent(c)}}return this.mouseUpHandler},mouseWheelHandler:null,getMouseWheel:function(){if(!this.mouseWheelHandler){var c=this;var b=new Date().getTime();this.mouseWheelHandler=function(g){var h=0;if(g.wheelDelta){h=g.wheelDelta}else{if(g.detail){h=-g.detail}}var f=new Date().getTime()-b;if(Math.abs(h)>0&&(f>200)){var d=c.getMousePoint(g);c.map.zoomByAbout(h>0?1:-1,d);b=new Date().getTime()}return a.cancelEvent(g)}}return this.mouseWheelHandler},doubleClickHandler:null,getDoubleClick:function(){if(!this.doubleClickHandler){var b=this;this.doubleClickHandler=function(d){var c=b.getMousePoint(d);b.map.zoomByAbout(d.shiftKey?-1:1,c);return a.cancelEvent(d)}}return this.doubleClickHandler},getMousePoint:function(d){var b=new a.Point(d.clientX,d.clientY);b.x+=document.body.scrollLeft+document.documentElement.scrollLeft;b.y+=document.body.scrollTop+document.documentElement.scrollTop;for(var c=this.map.parent;c;c=c.offsetParent){b.x-=c.offsetLeft;b.y-=c.offsetTop}return b}};a.Map=function(m,l,b,c){if(typeof m=="string"){m=document.getElementById(m)}this.parent=m;this.idBase=m.id;this.parent.style.padding="0";this.parent.style.overflow="hidden";var g=a.getStyle(this.parent,"position");if(g!="relative"&&g!="absolute"){this.parent.style.position="relative"}if(!b){var n=this.parent.offsetWidth;var f=this.parent.offsetHeight;if(!n){n=640;this.parent.style.width=n+"px"}if(!f){f=480;this.parent.style.height=f+"px"}b=new a.Point(n,f);var d=this;a.addEvent(window,"resize",function(h){d.dimensions=new a.Point(d.parent.offsetWidth,d.parent.offsetHeight);d.draw();d.dispatchCallback("resized",[d.dimensions])})}else{this.parent.style.width=Math.round(b.x)+"px";this.parent.style.height=Math.round(b.y)+"px"}this.dimensions=b;if(c===undefined){this.eventHandlers=[];this.eventHandlers.push(new a.MouseHandler(this))}else{this.eventHandlers=c;if(c instanceof Array){for(var e=0;e<c.length;e++){c[e].init(this)}}}this.loadingLayer=document.createElement("div");this.loadingLayer.id=this.idBase+"loading layer";this.loadingLayer.style.display="none";this.parent.appendChild(this.loadingLayer);this.layers=[];for(var k=0;k<=20;k++){var j=document.createElement("div");j.id=this.idBase+"zoom-"+k;j.style.margin="0";j.style.padding="0";j.style.width="100%";j.style.height="100%";j.style.position="absolute";j.style.top="0px";j.style.left="0px";this.parent.appendChild(j);this.layers.push(j)}this.coordinate=new a.Coordinate(0.5,0.5,0);this.setProvider(l);this.callbacks={zoomed:[],panned:[],centered:[],extentset:[],resized:[]}};a.Map.prototype={parent:null,provider:null,dimensions:null,coordinate:null,tiles:null,requestedTiles:null,layers:null,requestCount:null,maxSimultaneousRequests:null,requestQueue:null,tileCacheSize:null,maxTileCacheSize:null,recentTiles:null,recentTilesById:null,callbacks:null,eventHandlers:null,toString:function(){return"Map("+this.provider.toString()+this.dimensions.toString()+this.coordinate.toString()+")"},addCallback:function(b,c){if(typeof(c)=="function"&&this.callbacks[b]){this.callbacks[b].push(c)}},dispatchCallback:function(d,c){if(this.callbacks[d]){for(var b=0;b<this.callbacks[d].length;b+=1){try{this.callbacks[d][b](this,c)}catch(f){}}}},zoomIn:function(){this.zoomBy(1)},zoomOut:function(){this.zoomBy(-1)},setZoom:function(b){this.zoomBy(b-this.coordinate.zoom)},zoomBy:function(b){this.coordinate=this.coordinate.zoomBy(b);this.draw();this.dispatchCallback("zoomed",b)},zoomByAbout:function(c,b){var e=this.pointLocation(b);this.coordinate=this.coordinate.zoomBy(c);var d=this.locationPoint(e);this.panBy(b.x-d.x,b.y-d.y);this.dispatchCallback("zoomed",c)},panBy:function(c,b){this.coordinate.column-=c/this.provider.tileWidth;this.coordinate.row-=b/this.provider.tileHeight;this.draw();this.dispatchCallback("panned",[c,b])},panLeft:function(){this.panBy(100,0)},panRight:function(){this.panBy(-100,0)},panDown:function(){this.panBy(0,-100)},panUp:function(){this.panBy(0,100)},setCenter:function(b){this.setCenterZoom(b,this.coordinate.zoom)},setCenterZoom:function(b,c){this.coordinate=this.provider.locationCoordinate(b).zoomTo(c);this.draw();this.dispatchCallback("centered",[b,c])},setExtent:function(k){var h,g;for(var f=0;f<k.length;f++){var q=this.provider.locationCoordinate(k[f]);if(h){h.row=Math.min(h.row,q.row);h.column=Math.min(h.column,q.column);h.zoom=Math.min(h.zoom,q.zoom);g.row=Math.max(g.row,q.row);g.column=Math.max(g.column,q.column);g.zoom=Math.max(g.zoom,q.zoom)}else{h=q.copy();g=q.copy()}}var c=this.dimensions.x+1;var r=this.dimensions.y+1;var b=(g.column-h.column)/(c/this.provider.tileWidth);var l=Math.log(b)/Math.log(2);var m=h.zoom-Math.ceil(l);var n=(g.row-h.row)/(r/this.provider.tileHeight);var s=Math.log(n)/Math.log(2);var p=h.zoom-Math.ceil(s);var d=Math.min(m,p);var e=(h.row+g.row)/2;var j=(h.column+g.column)/2;var o=h.zoom;this.coordinate=new a.Coordinate(e,j,o).zoomTo(d);this.draw();this.dispatchCallback("extentset",k)},setSize:function(c,b){if(c.hasOwnProperty("x")&&c.hasOwnProperty("y")){this.dimensions=c}else{if(b!==undefined&&!isNaN(b)){this.dimensions=new a.Point(c,b)}}this.parent.style.width=Math.round(this.dimensions.x)+"px";this.parent.style.height=Math.round(this.dimensions.y)+"px";this.draw();this.dispatchCallback("resized",[this.dimensions])},coordinatePoint:function(c){if(c.zoom!=this.coordinate.zoom){c=c.zoomTo(this.coordinate.zoom)}var b=new a.Point(this.dimensions.x/2,this.dimensions.y/2);b.x+=this.provider.tileWidth*(c.column-this.coordinate.column);b.y+=this.provider.tileHeight*(c.row-this.coordinate.row);return b},pointCoordinate:function(b){var c=this.coordinate.copy();c.column+=(b.x-this.dimensions.x/2)/this.provider.tileWidth;c.row+=(b.y-this.dimensions.y/2)/this.provider.tileHeight;return c},locationPoint:function(b){return this.coordinatePoint(this.provider.locationCoordinate(b))},pointLocation:function(b){return this.provider.coordinateLocation(this.pointCoordinate(b))},getExtent:function(){var b=[];b.push(this.pointLocation(new a.Point(0,0)));b.push(this.pointLocation(this.dimensions));return b},getCenter:function(){return this.provider.coordinateLocation(this.coordinate)},getZoom:function(){return this.coordinate.zoom},setProvider:function(d){var e=false;if(this.provider===null){e=true}if(!e){for(var g in this.requestedTiles){if(this.requestedTiles.hasOwnProperty(g)){var f=this.requestedTiles[g];this.cancelTileRequest(f);f=null}}for(var c=0;c<this.layers.length;c+=1){var b=this.layers[c];while(b.firstChild){b.removeChild(b.firstChild)}}}this.tiles={};this.requestedTiles={};this.requestCount=0;this.maxSimultaneousRequests=4;this.requestQueue=[];this.tileCacheSize=0;this.maxTileCacheSize=64;this.recentTiles=[];this.recentTilesById={};this.provider=d;if(!e){this.draw()}},getStats:function(){return{"Request Queue Length":this.requestQueue.length,"Open Request Count":this.requestCount,"Tile Cache Size":this.tileCacheSize,"Tiles On Screen":this.parent.getElementsByTagName("img").length}},draw:function(){var B=this.coordinate.container();var C=new a.Point(this.dimensions.x/2,this.dimensions.y/2);C.x+=(B.column-this.coordinate.column)*this.provider.tileWidth;C.y+=(B.row-this.coordinate.row)*this.provider.tileHeight;while(C.x>0){C.x-=this.provider.tileWidth;B.column-=1}while(C.y>0){C.y-=this.provider.tileHeight;B.row-=1}var e={};var k=this.layers[B.zoom];k.coordinate=B.copy();var c=B.copy();var t=this.dimensions.y;var v=this.dimensions.x;var h=this.provider.tileHeight;var p=this.provider.tileWidth;for(var m=C.y;m<t;m+=h){for(var n=C.x;n<v;n+=p){var l=c.toKey();e[l]=true;if(!this.tiles[l]){if(!this.requestedTiles[l]){this.requestTile(c)}for(var o=1;o<=5;o++){var r=c.zoomBy(-o).container().toKey();e[r]=true}var g=c.zoomBy(1);e[g.toKey()]=true;g.column+=1;e[g.toKey()]=true;g.row+=1;e[g.toKey()]=true;g.column-=1;e[g.toKey()]=true}else{var F=this.tiles[l];if(F.parentNode!=k){k.appendChild(F)}}c.column+=1}c.row+=1;c.column=B.column}for(var s=0;s<this.layers.length;s++){if(s>=B.zoom-5&&s<B.zoom+2){continue}var E=this.layers[s];E.style.display="none";var A=E.getElementsByTagName("img");for(var q=A.length-1;q>=0;q--){E.removeChild(A[q])}}var d=new Date().getTime();var u=Math.max(0,B.zoom-5);var f=Math.min(B.zoom+2,this.layers.length);for(var s=u;s<f;s++){var E=this.layers[s];var b=null;var D=1;if(E.coordinate){E.style.display="block";b=this.coordinate.zoomTo(E.coordinate.zoom);D=Math.pow(2,this.coordinate.zoom-E.coordinate.zoom)}else{E.style.display="none"}var A=E.getElementsByTagName("img");for(var q=A.length-1;q>=0;q--){var F=A[q];if(!e[F.id]){E.removeChild(F)}else{var z=((this.dimensions.x/2)+(F.coord.column-b.column)*this.provider.tileWidth*D);var w=((this.dimensions.y/2)+(F.coord.row-b.row)*this.provider.tileHeight*D);F.style.left=z+"px";F.style.top=w+"px";F.width=this.provider.tileWidth*D;F.height=this.provider.tileHeight*D;this.recentTilesById[F.id].lastTouchedTime=d}}}for(var l in this.requestedTiles){if(this.requestedTiles.hasOwnProperty(l)){if(!(l in e)){var F=this.requestedTiles[l];this.cancelTileRequest(F);F=null}}}this.processQueue();this.checkCache()},redrawTimer:undefined,requestRedraw:function(){if(this.redrawTimer){clearTimeout(this.redrawTimer)}this.redrawTimer=setTimeout(this.getRedraw(),1000)},_redraw:null,getRedraw:function(){if(!this._redraw){var b=this;this._redraw=function(){b.draw()}}return this._redraw},requestTile:function(b){var e=b.toKey();if(!this.requestedTiles[e]){var c=document.createElement("img");this.requestedTiles[e]=c;var d=this.provider.getTileUrl(b);if(d){c.id=e;c.width=this.provider.tileWidth;c.height=this.provider.tileHeight;c.style.position="absolute";c.coord=b.copy();this.requestQueue.push({tile:c,url:d})}}},checkCache:function(){var f=this.parent.getElementsByTagName("img").length;var d=Math.max(f,this.maxTileCacheSize);if(this.tileCacheSize>d){this.recentTiles.sort(function(h,g){return g.lastTouchedTime-h.lastTouchedTime})}while(this.tileCacheSize>d){var c=this.recentTiles.pop();var b=new Date().getTime();delete this.recentTilesById[c.id];var e=this.tiles[c.id];if(e.parentNode){alert("Gah: trying to removing cached tile even though it's still in the DOM")}else{delete this.tiles[c.id];this.tileCacheSize--}}},processQueue:function(){if(this.requestQueue.length>8){this.requestQueue.sort(this.getCenterDistanceCompare())}while(this.requestCount<this.maxSimultaneousRequests&&this.requestQueue.length>0){var b=this.requestQueue.pop();if(b){this.requestCount++;this.loadingLayer.appendChild(b.tile);b.tile.onload=b.tile.onerror=this.getLoadComplete();b.tile.src=b.url;b.tile=b.url=null}}},cancelTileRequest:function(d){delete this.requestedTiles[d.id];if(d.src){d.onload=d.onerror=null;d.coord=null;d.src=null;this.loadingLayer.removeChild(d);this.requestCount--}else{for(var b=0;b<this.requestQueue.length;b++){var c=this.requestQueue[b];if(c&&c.tile===d){this.requestQueue[b]=null;c.tile=c.tile.coord=c.url=null}}}},_loadComplete:null,getLoadComplete:function(){if(!this._loadComplete){var b=this;this._loadComplete=function(j){j=j||window.event;var h=j.srcElement||j.target;h.onload=h.onerror=null;b.loadingLayer.removeChild(h);b.requestCount--;delete b.requestedTiles[h.id];if(h.complete||(h.readyState&&h.readyState=="complete")){b.tiles[h.id]=h;b.tileCacheSize++;var f={id:h.id,lastTouchedTime:new Date().getTime()};b.recentTilesById[h.id]=f;b.recentTiles.push(f);var i=b.layers[h.coord.zoom];i.appendChild(h);var g=b.coordinate.zoomTo(i.coordinate.zoom);var k=Math.pow(2,b.coordinate.zoom-i.coordinate.zoom);var d=((b.dimensions.x/2)+(h.coord.column-g.column)*b.provider.tileWidth*k);var c=((b.dimensions.y/2)+(h.coord.row-g.row)*b.provider.tileHeight*k);h.style.left=d+"px";h.style.top=c+"px";h.width=b.provider.tileWidth*k;h.height=b.provider.tileHeight*k}else{h.src=null}b.processQueue();b.requestRedraw()}}return this._loadComplete},getCenterDistanceCompare:function(){var b=this.coordinate.copy();return function(e,d){if(e&&d){var g=e.tile.coord;var f=d.tile.coord;var c=Math.abs(b.row-g.row-0.5)+Math.abs(b.column-g.column-0.5);var h=Math.abs(b.row-f.row-0.5)+Math.abs(b.column-f.column-0.5);return c<h?1:c>h?-1:0}return e?1:d?-1:0}}}})(com.modestmaps);
