Skip to content
Browse files

couple of speed enhancements to js/examples/touch and fixes for ipads

git-svn-id: https://modestmaps.googlecode.com/svn/trunk/js@923 a23cadb0-8de1-11de-82e5-a1837a67dc72
  • Loading branch information...
1 parent 9832a73 commit 7618308e1318daf3aca71382b70f5decf66a83a1 tom.carden committed Jul 20, 2010
Showing with 488 additions and 425 deletions.
  1. +3 −0 CHANGELOG
  2. +36 −391 examples/touch/index.html
  3. +83 −0 examples/touch/test.html
  4. +355 −0 examples/touch/touch.js
  5. +0 −10 examples/touch/trace.php
  6. +0 −17 examples/touch/underscore-min.js
  7. +9 −5 modestmaps.js
  8. +2 −2 modestmaps.min.js
View
3 CHANGELOG
@@ -8,6 +8,9 @@ Following the semantic versioning recommendation best we can:
minor version, and backwards incompatible API changes increment
the major version." -- http://semver.org/
+v0.13.4
+ - changed to img.style.width instead of img.width, for ipads (see examples/touch/test.html)
+
v0.13.3
- stubbed out tilePadding into Map.draw
View
427 examples/touch/index.html
@@ -1,399 +1,44 @@
+<!DOCTYPE html>
<html>
-<head>
-<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" />
-<meta name="apple-mobile-web-app-status-bar-style" content="black" />
-<meta name="apple-mobile-web-app-capable" content="yes" />
-<title>Modest Maps JS - Touch Tester</title>
-<script type="text/javascript" src="underscore-min.js"></script>
-<script type="text/javascript" src="../../modestmaps.js"></script>
-<script type="text/javascript">
-
-(function(MM){
-
- function stderr(msg)
- {
- return;
- req = new XMLHttpRequest();
- req.open('POST', 'trace.php', false);
- req.send(msg);
- }
-
- function distance(t1, t2)
- {
- return Math.sqrt(Math.pow(t1.screenX - t2.screenX, 2) + Math.pow(t1.screenY - t2.screenY, 2));
- }
-
- function Start(touch, time)
- {
- this.screenX = touch.screenX;
- this.screenY = touch.screenY;
-
- this.touch = touch;
- this.time = time;
-
- // the pointer chase ends here
- this.start = this;
- this.count = 0;
- this.travel = 0;
- this.last = null;
- }
-
- function Move(touch, last, time)
- {
- moved = distance(touch, last);
-
- this.screenX = touch.screenX;
- this.screenY = touch.screenY;
-
- this.touch = touch;
- this.time = time;
-
- // pointer chase
- this.start = last.start;
- this.count = last.count + 1;
- this.travel = last.travel + moved;
- this.last = last;
- }
-
- function Tap(x, y, time)
- {
- this.x = x;
- this.y = y;
- this.time = time;
- }
-
- function Hold(x, y, end, duration)
- {
- this.x = x;
- this.y = y;
- this.end = end;
- this.duration = duration;
- }
-
- function hasattr(obj, attr)
- {
- return _.any(_.keys(obj), function(key) { return key == attr });
- }
-
- function sameTouch(event, touch)
- {
- if(typeof event == 'object' && hasattr(event, 'touch'))
- {
- return touch == event.touch;
- }
- }
-
- function interruptTouches(events)
- {
- var now = new Date().getTime();
-
- for(var i = 0; i < events.length; i += 1)
- {
- var touch = events[i].touch;
- var start = new Start(touch, now);
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" />
+ <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <title>Modest Maps JS - Touch Tester</title>
+ <script type="text/javascript" src="../../modestmaps.js"></script>
+ <script type="text/javascript" src="touch.js"></script>
+ <script type="text/javascript">
- events[i] = start;
- }
- }
-
- function oneTouchMatrix(touch)
- {
- var start = touch.start;
-
- var x = touch.screenX - start.screenX;
- var y = touch.screenY - start.screenY;
-
- return [1, 0, 0, 1, x, y];
- }
-
- function twoTouchMatrix(t1, t2)
- {
- var t1_ = t1.start;
- var t2_ = t2.start;
-
- var span = distance(t1, t2);
- var span_ = distance(t1_, t2_);
-
- var s = span / span_;
-
- var x = (t1.screenX + t2.screenX) / 2;
- var y = (t1.screenY + t2.screenY) / 2;
- var x_ = (t1_.screenX + t2_.screenX) / 2;
- var y_ = (t1_.screenY + t2_.screenY) / 2;
-
- var tx = s * -x_ + x;
- var ty = s * -y_ + y;
-
- return [s, 0, 0, s, tx, ty];
- }
-
- MM.TouchHandler = function() { }
-
- MM.TouchHandler.prototype = {
-
- maxTapTime: 150,
- maxTapDistance: 10,
- maxDoubleTapDelay: 350,
- events: [],
- taps: [],
-
- init: function(map) {
- this.map = map;
- /*
- MM.addEvent(map.parent, 'touchstart', this.getDoubleTap());
- MM.addEvent(map.parent, 'touchstart', this.getTouchStart());
- MM.addEvent(map.parent, 'gesturestart', this.getGestureStart());
- */
-
- MM.addEvent(map.parent, 'touchstart', this.getTouchStartMachine());
- MM.addEvent(map.parent, 'touchmove', this.getTouchMoveMachine());
- MM.addEvent(map.parent, 'touchend', this.getTouchEndMachine());
- },
-
- getTouchStartMachineHandler: null,
-
- getTouchStartMachine: function() {
- if (!this.getTouchStartMachineHandler) {
- var theHandler = this;
- var events = this.events;
-
- this.getTouchStartMachineHandler = function(e)
- {
- interruptTouches(events);
-
- for(var i = 0; i < e.changedTouches.length; i += 1)
- {
- var touch = e.changedTouches[i];
- var start = new Start(touch, new Date().getTime());
-
- events.push(start);
- }
-
- return MM.cancelEvent(e);
- }
- }
- return this.getTouchStartMachineHandler;
- },
-
- getTouchStartMachineHandler: null,
-
- getTouchMoveMachine: function() {
- if (!this.getTouchMoveMachineHandler) {
- var theHandler = this;
- var events = this.events;
-
- this.getTouchMoveMachineHandler = function(e)
- {
- var now = new Date().getTime();
-
- /**
- * Look at each changed touch in turn.
- */
- for(var i = 0; i < e.changedTouches.length; i += 1)
- {
- var touch = e.changedTouches[i];
-
- for(var j = 0; j < events.length; j += 1)
- {
- if(sameTouch(events[j], touch))
- {
- events[j] = new Move(touch, events[j], now);
- }
- }
- }
-
- if(events.length == 1) {
- theHandler.onPanning(events[0]);
-
- } else if(events.length == 2) {
- theHandler.onPinching(events[0], events[1]);
- }
-
- return MM.cancelEvent(e);
- }
- }
- return this.getTouchMoveMachineHandler;
- },
-
- getTouchEndMachineHandler: null,
-
- getTouchEndMachine: function() {
- if (!this.getTouchEndMachineHandler) {
- var theHandler = this;
- var events = this.events;
-
- this.getTouchEndMachineHandler = function(e)
- {
- var now = new Date().getTime();
-
- if(events.length == 1) {
- theHandler.onPanned(events[0]);
-
- } else if(events.length == 2) {
- theHandler.onPinched(events[0], events[1]);
- }
-
- /**
- * Look at each changed touch in turn.
- */
- for(var i = 0; i < e.changedTouches.length; i += 1)
- {
- var touch = e.changedTouches[i];
-
- for(var j = 0; j < events.length; j += 1)
- {
- if(sameTouch(events[j], touch))
- {
- var event = new Move(touch, events[j], now);
-
- stderr('End of the line for touch #' + touch.identifier + ', c=' + event.count + ', ' + (now - event.start.time) + 'ms, ' + event.travel.toFixed(0) + 'px');
- events.splice(j, 1);
- j -= 1;
-
- // we now know we have an event object and a
- // matching touch that's just ended. Let's see
- // what kind of event it is based on how long it
- // lasted and how far it moved.
-
- var time = now - event.start.time;
-
- if(event.travel > theHandler.maxTapDistance) {
- // we will to assume that the drag has been handled separately
-
- } else if(time > theHandler.maxTapTime) {
- // close in time, but not in space: a hold
- var hold = new Hold(touch.screenX, touch.screenY, now, time);
- theHandler.onHold(hold);
-
- } else {
- // close in both time and space: a tap
- var tap = new Tap(touch.screenX, touch.screenY, now);
- theHandler.onTap(tap);
- }
- }
- }
- }
-
- interruptTouches(events);
-
- if(e.touches.length == 0 && events.length >= 1)
- {
- // Weird, sometimes an end event doesn't get thrown
- // for a touch that nevertheless has disappeared.
- events.splice(0, events.length);
- }
-
- return MM.cancelEvent(e);
- }
- }
- return this.getTouchEndMachineHandler;
- },
-
- onHold: function(hold)
- {
- stderr('Hold: (' + hold.x + ', ' + hold.y + ') for ' + hold.duration + ' msec');
- },
-
- onTap: function(tap)
- {
- if(this.taps.length && (tap.time - this.taps[0].time) < this.maxDoubleTapDelay)
- {
- this.onDoubleTap(tap);
- return;
- }
+ var map;
- stderr('Tap: (' + tap.x + ', ' + tap.y + ')');
+ function initMap() {
- this.taps = [tap];
- },
-
- onDoubleTap: function(tap)
- {
- stderr('Double-tap: (' + tap.x + ', ' + tap.y + ')');
+ var template = 'http://{S}tile.openstreetmap.org/{Z}/{X}/{Y}.png';
+ var subdomains = [ '', 'a.', 'b.', 'c.' ];
+ var provider = new com.modestmaps.TemplatedMapProvider(template, subdomains);
- // zoom in to a round number
- var z = Math.floor(this.map.getZoom() + 2);
- z = z - this.map.getZoom();
-
- var p = new MM.Point(tap.x, tap.y);
+ map = new com.modestmaps.Map('map',
+ provider,
+ null,
+ [ new com.modestmaps.TouchHandler() ]);
- this.map.zoomByAbout(z, p);
- },
-
- onPanning: function(touch)
- {
- var m = oneTouchMatrix(touch);
- m = ['1', '0', '0', '1', m[4].toFixed(0), m[5].toFixed(0)];
- m = 'matrix(' + m.join(', ') + ')';
+ map.setCenterZoom(new com.modestmaps.Location(37.811530, -122.2666097), 14);
- this.map.parent.style.webkitTransformOrigin = '0px 0px';
- this.map.parent.style.webkitTransform = m;
- },
-
- onPanned: function(touch)
- {
- var m = oneTouchMatrix(touch);
-
- stderr('Pan by ' + m[4].toFixed(0) + ', ' + m[5].toFixed(0));
-
- this.map.panBy(m[4], m[5]);
- this.map.parent.style.webkitTransform = '';
- },
-
- onPinching: function(touch1, touch2)
- {
- var m = twoTouchMatrix(touch1, touch2);
- m = [m[0].toFixed(3), '0', '0', m[3].toFixed(3), m[4].toFixed(0), m[5].toFixed(0)];
- m = 'matrix(' + m.join(', ') + ')';
-
- this.map.parent.style.webkitTransformOrigin = '0px 0px';
- this.map.parent.style.webkitTransform = m;
- },
-
- onPinched: function(touch1, touch2)
- {
- var m = twoTouchMatrix(touch1, touch2);
- var z = Math.log(m[0]) / Math.log(2);
- var p = new MM.Point(0, 0);
-
- stderr('Zoom by ' + z.toFixed(3) + ' about ' + p.toString());
- stderr('Pan by ' + m[4].toFixed(0) + ', ' + m[5].toFixed(0));
+ }
- this.map.zoomByAbout(z, p);
- this.map.panBy(m[4], m[5]);
- this.map.parent.style.webkitTransform = '';
- }
-
- };
-
-})(com.modestmaps);
-
-var map;
-
-function initMap() {
-
- var container = document.getElementById('container');
-
- map = new com.modestmaps.Map('map',
- new com.modestmaps.TemplatedMapProvider('http://tile.openstreetmap.org/{Z}/{X}/{Y}.png'),
- new com.modestmaps.Point(container.offsetWidth, container.offsetHeight),
- [ new com.modestmaps.TouchHandler() ]);
-
- map.setCenterZoom(new com.modestmaps.Location(37.811530, -122.2666097), 14);
-
- window.onresize = function() {
- map.setSize(container.offsetWidth, container.offsetHeight);
- };
-
- stderr('------------------------------------------------------------------------');
-}
-
-</script>
-</head>
-<body onload="initMap()" style="margin:0; padding:0; border:0">
-<div id="container" style="width: 100%; height: 100%; -webkit-touch-callout: none; -webkit-user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0);">
- <div id="map">
- </div>
-</div>
-</body>
-</html>
+ </script>
+ <style type="text/css">
+ html, body, #map {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ }
+ </style>
+ </head>
+ <body onload="initMap()">
+ <div id="map">
+ </div>
+ </body>
+</html>
View
83 examples/touch/test.html
@@ -0,0 +1,83 @@
+<html>
+<body>
+
+<h1>Image Scaling With Width and Height:</h1>
+
+<p>256x256
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256">
+
+<p>512x512
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="512" height="512">
+
+<p>1024x1024
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="1024" height="1024">
+
+<p>2048x2048
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="2048" height="2048">
+
+<p>4096x4096
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="4096" height="4096">
+
+<h1>Image Scaling With CSS and width/height set:</h1>
+
+<p>256x256
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="width: 256px; height: 256px;">
+
+<p>512x512
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="width: 512px; height: 512px;">
+
+<p>1024x1024
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="width: 1024px; height: 1024px;">
+
+<p>2048x2048
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="width: 2048px; height: 2048px;">
+
+<p>4096x4096
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="width: 4096px; height: 4096px;">
+
+<h1>Image Scaling With CSS without width/height set:</h1>
+
+<p>256x256
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" style="width: 256px; height: 256px;">
+
+<p>512x512
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" style="width: 512px; height: 512px;">
+
+<p>1024x1024
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" style="width: 1024px; height: 1024px;">
+
+<p>1400x1400
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" style="width: 1400px; height: 1400px;">
+
+<p>2048x2048
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" style="width: 2048px; height: 2048px;">
+
+<p>2500x2500
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" style="width: 2500px; height: 2500px;">
+
+<p>4096x4096
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" style="width: 4096px; height: 4096px;">
+
+<!--
+
+<h1>Image Scaling With -webkit-transform:</h1>
+
+<p>1x
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="-webkit-transform: scale3d(1,1,1); -webkit-transform-origin: 0px 0px;">
+
+<p>2x
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="-webkit-transform: scale3d(2,2,1); -webkit-transform-origin: 0px 0px;">
+
+<p>4x
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="-webkit-transform: scale3d(4,4,1); -webkit-transform-origin: 0px 0px;">
+
+<p>8x
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="-webkit-transform: scale3d(8,8,1); -webkit-transform-origin: 0px 0px;">
+
+<p>16x
+<img src="http://tile.openstreetmap.org/14/2626/6330.png" width="256" height="256" style="-webkit-transform: scale3d(16,16,1); -webkit-transform-origin: 0px 0px;">
+
+-->
+
+</body>
+</html>
View
355 examples/touch/touch.js
@@ -0,0 +1,355 @@
+(function(MM){
+
+ function distance(t1, t2)
+ {
+ return Math.sqrt(Math.pow(t1.screenX - t2.screenX, 2) + Math.pow(t1.screenY - t2.screenY, 2));
+ }
+
+ function Start(touch, time)
+ {
+ this.screenX = touch.screenX;
+ this.screenY = touch.screenY;
+
+ this.touch = touch;
+ this.time = time;
+
+ // the pointer chase ends here
+ this.start = this;
+ this.count = 0;
+ this.travel = 0;
+ this.last = null;
+ }
+
+ function Move(touch, last, time)
+ {
+ moved = distance(touch, last);
+
+ this.screenX = touch.screenX;
+ this.screenY = touch.screenY;
+
+ this.touch = touch;
+ this.time = time;
+
+ // pointer chase
+ this.start = last.start;
+ this.count = last.count + 1;
+ this.travel = last.travel + moved;
+ this.last = last;
+ }
+
+ function Tap(x, y, time)
+ {
+ this.x = x;
+ this.y = y;
+ this.time = time;
+ }
+
+ function Hold(x, y, end, duration)
+ {
+ this.x = x;
+ this.y = y;
+ this.end = end;
+ this.duration = duration;
+ }
+
+ function sameTouch(event, touch)
+ {
+ if(event && event.touch)
+ {
+ return touch == event.touch;
+ }
+ }
+
+ function interruptTouches(events)
+ {
+ var now = new Date().getTime();
+
+ for(var i = 0; i < events.length; i += 1)
+ {
+ var touch = events[i].touch;
+ var start = new Start(touch, now);
+
+ events[i] = start;
+ }
+ }
+
+ function oneTouchMatrix(touch)
+ {
+ var start = touch.start;
+
+ var x = touch.screenX - start.screenX;
+ var y = touch.screenY - start.screenY;
+
+ return [1, 0, 0, 1, x, y];
+ }
+
+ function twoTouchMatrix(t1, t2)
+ {
+ var t1_ = t1.start;
+ var t2_ = t2.start;
+
+ var span = distance(t1, t2);
+ var span_ = distance(t1_, t2_);
+
+ var s = span / span_;
+
+ var x = (t1.screenX + t2.screenX) / 2;
+ var y = (t1.screenY + t2.screenY) / 2;
+ var x_ = (t1_.screenX + t2_.screenX) / 2;
+ var y_ = (t1_.screenY + t2_.screenY) / 2;
+
+ var tx = s * -x_ + x;
+ var ty = s * -y_ + y;
+
+ return [s, 0, 0, s, tx, ty];
+ }
+
+ MM.TouchHandler = function() { }
+
+ MM.TouchHandler.prototype = {
+
+ maxTapTime: 150,
+ maxTapDistance: 10,
+ maxDoubleTapDelay: 350,
+ events: [],
+ taps: [],
+
+ init: function(map) {
+ this.map = map;
+ /*
+ MM.addEvent(map.parent, 'touchstart', this.getDoubleTap());
+ MM.addEvent(map.parent, 'touchstart', this.getTouchStart());
+ MM.addEvent(map.parent, 'gesturestart', this.getGestureStart());
+ */
+
+ MM.addEvent(map.parent, 'touchstart', this.getTouchStartMachine());
+ MM.addEvent(map.parent, 'touchmove', this.getTouchMoveMachine());
+ MM.addEvent(map.parent, 'touchend', this.getTouchEndMachine());
+ },
+
+ getTouchStartMachineHandler: null,
+
+ getTouchStartMachine: function() {
+ if (!this.getTouchStartMachineHandler) {
+ var theHandler = this;
+ var events = this.events;
+
+ this.getTouchStartMachineHandler = function(e)
+ {
+ interruptTouches(events);
+
+ for(var i = 0; i < e.changedTouches.length; i += 1)
+ {
+ var touch = e.changedTouches[i];
+ var start = new Start(touch, new Date().getTime());
+
+ events.push(start);
+ }
+
+ return MM.cancelEvent(e);
+ }
+ }
+ return this.getTouchStartMachineHandler;
+ },
+
+ getTouchStartMachineHandler: null,
+
+ getTouchMoveMachine: function() {
+ if (!this.getTouchMoveMachineHandler) {
+ var theHandler = this;
+ var events = this.events;
+
+ this.getTouchMoveMachineHandler = function(e)
+ {
+ var now = new Date().getTime();
+
+ /**
+ * Look at each changed touch in turn.
+ */
+ for(var i = 0; i < e.changedTouches.length; i += 1)
+ {
+ var touch = e.changedTouches[i];
+
+ for(var j = 0; j < events.length; j += 1)
+ {
+ if(sameTouch(events[j], touch))
+ {
+ events[j] = new Move(touch, events[j], now);
+ }
+ }
+ }
+
+ if(events.length == 1) {
+ theHandler.onPanning(events[0]);
+
+ } else if(events.length == 2) {
+ theHandler.onPinching(events[0], events[1]);
+ }
+
+ return MM.cancelEvent(e);
+ }
+ }
+ return this.getTouchMoveMachineHandler;
+ },
+
+ getTouchEndMachineHandler: null,
+
+ getTouchEndMachine: function() {
+ if (!this.getTouchEndMachineHandler) {
+ var theHandler = this;
+ var events = this.events;
+
+ this.getTouchEndMachineHandler = function(e)
+ {
+ var now = new Date().getTime();
+
+ if(events.length == 1) {
+ theHandler.onPanned(events[0]);
+
+ } else if(events.length == 2) {
+ theHandler.onPinched(events[0], events[1]);
+ }
+
+ /**
+ * Look at each changed touch in turn.
+ */
+ for(var i = 0; i < e.changedTouches.length; i += 1)
+ {
+ var touch = e.changedTouches[i];
+
+ for(var j = 0; j < events.length; j += 1)
+ {
+ if(sameTouch(events[j], touch))
+ {
+ var event = new Move(touch, events[j], now);
+
+ //stderr('End of the line for touch #' + touch.identifier + ', c=' + event.count + ', ' + (now - event.start.time) + 'ms, ' + event.travel.toFixed(0) + 'px');
+
+ events.splice(j, 1);
+ j -= 1;
+
+ // we now know we have an event object and a
+ // matching touch that's just ended. Let's see
+ // what kind of event it is based on how long it
+ // lasted and how far it moved.
+
+ var time = now - event.start.time;
+
+ if(event.travel > theHandler.maxTapDistance) {
+ // we will to assume that the drag has been handled separately
+
+ } else if(time > theHandler.maxTapTime) {
+ // close in time, but not in space: a hold
+ var hold = new Hold(touch.screenX, touch.screenY, now, time);
+ theHandler.onHold(hold);
+
+ } else {
+ // close in both time and space: a tap
+ var tap = new Tap(touch.screenX, touch.screenY, now);
+ theHandler.onTap(tap);
+ }
+ }
+ }
+ }
+
+ interruptTouches(events);
+
+ if(e.touches.length == 0 && events.length >= 1)
+ {
+ // Weird, sometimes an end event doesn't get thrown
+ // for a touch that nevertheless has disappeared.
+ events.splice(0, events.length);
+ }
+
+ return MM.cancelEvent(e);
+ }
+ }
+ return this.getTouchEndMachineHandler;
+ },
+
+ onHold: function(hold)
+ {
+ //stderr('Hold: (' + hold.x + ', ' + hold.y + ') for ' + hold.duration + ' msec');
+ },
+
+ onTap: function(tap)
+ {
+ if(this.taps.length && (tap.time - this.taps[0].time) < this.maxDoubleTapDelay)
+ {
+ this.onDoubleTap(tap);
+ return;
+ }
+
+ //stderr('Tap: (' + tap.x + ', ' + tap.y + ')');
+
+ this.taps = [tap];
+ },
+
+ onDoubleTap: function(tap)
+ {
+ //stderr('Double-tap: (' + tap.x + ', ' + tap.y + ')');
+
+ // zoom in to a round number
+ var z = Math.floor(this.map.getZoom() + 2);
+ z = z - this.map.getZoom();
+
+ var p = new MM.Point(tap.x, tap.y);
+
+ this.map.zoomByAbout(z, p);
+ },
+
+ onPanning: function(touch)
+ {
+ var m = oneTouchMatrix(touch);
+ //m = ['1', '0', '0', '1', m[4].toFixed(0), m[5].toFixed(0)];
+ //m = 'matrix(' + m.join(', ') + ')';
+ // http://www.w3.org/TR/css3-3d-transforms/#transform-functions
+ // matrix(a,b,c,d,e,f) is equivalent to matrix3d(a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, e, f, 0, 1)
+ m = ['1', '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', m[4].toFixed(0), m[5].toFixed(0), '0', '1'];
+ m = 'matrix3d(' + m.join(', ') + ')';
+
+ this.map.parent.style.webkitTransformOrigin = '0px 0px';
+ this.map.parent.style.webkitTransform = m;
+ },
+
+ onPanned: function(touch)
+ {
+ var m = oneTouchMatrix(touch);
+
+ //stderr('Pan by ' + m[4].toFixed(0) + ', ' + m[5].toFixed(0));
+
+ this.map.panBy(m[4], m[5]);
+ this.map.parent.style.webkitTransform = '';
+ },
+
+ onPinching: function(touch1, touch2)
+ {
+ var m = twoTouchMatrix(touch1, touch2);
+ //m = [m[0].toFixed(3), '0', '0', m[3].toFixed(3), m[4].toFixed(0), m[5].toFixed(0)];
+ //m = 'matrix(' + m.join(', ') + ')';
+ // http://www.w3.org/TR/css3-3d-transforms/#transform-functions
+ // matrix(a,b,c,d,e,f) is equivalent to matrix3d(a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, e, f, 0, 1)
+ m = [m[0].toFixed(3), '0', '0', '0', '0', m[3].toFixed(3), '0', '0', '0', '0', '1', '0', m[4].toFixed(0), m[5].toFixed(0), '0', '1'];
+ m = 'matrix3d(' + m.join(', ') + ')';
+
+ this.map.parent.style.webkitTransformOrigin = '0px 0px';
+ this.map.parent.style.webkitTransform = m;
+ },
+
+ onPinched: function(touch1, touch2)
+ {
+ var m = twoTouchMatrix(touch1, touch2);
+ var z = Math.log(m[0]) / Math.log(2);
+ var p = new MM.Point(0, 0);
+
+ //stderr('Zoom by ' + z.toFixed(3) + ' about ' + p.toString());
+ //stderr('Pan by ' + m[4].toFixed(0) + ', ' + m[5].toFixed(0));
+
+ this.map.zoomByAbout(z, p);
+ this.map.panBy(m[4], m[5]);
+ this.map.parent.style.webkitTransform = '';
+ }
+
+ };
+
+})(com.modestmaps);
View
10 examples/touch/trace.php
@@ -1,10 +0,0 @@
-<?php
-
- if(($in = fopen('php://input', 'r')) && ($out = fopen('what.txt', 'a')))
- {
- fwrite($out, fread($in, 1024)."\n");
- fclose($in);
- fclose($out);
- }
-
-?>
View
17 examples/touch/underscore-min.js
@@ -1,17 +0,0 @@
-(function(){var n=this,A=n._,r=typeof StopIteration!=="undefined"?StopIteration:"__break__",B=function(a){return a.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},j=Array.prototype,l=Object.prototype,o=j.slice,C=j.unshift,D=l.toString,p=l.hasOwnProperty,s=j.forEach,t=j.map,u=j.reduce,v=j.reduceRight,w=j.filter,x=j.every,y=j.some,m=j.indexOf,z=j.lastIndexOf;l=Array.isArray;var E=Object.keys,b=function(a){return new k(a)};if(typeof exports!=="undefined")exports._=b;n._=b;b.VERSION="1.0.2";var i=b.forEach=
-function(a,c,d){try{if(s&&a.forEach===s)a.forEach(c,d);else if(b.isNumber(a.length))for(var e=0,f=a.length;e<f;e++)c.call(d,a[e],e,a);else for(e in a)p.call(a,e)&&c.call(d,a[e],e,a)}catch(g){if(g!=r)throw g;}return a};b.map=function(a,c,d){if(t&&a.map===t)return a.map(c,d);var e=[];i(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(u&&a.reduce===u)return a.reduce(b.bind(d,e),c);i(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(v&&
-a.reduceRight===v)return a.reduceRight(b.bind(d,e),c);a=b.clone(b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.detect=function(a,c,d){var e;i(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.filter=function(a,c,d){if(w&&a.filter===w)return a.filter(c,d);var e=[];i(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];i(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.every=function(a,c,d){c=c||b.identity;if(x&&a.every===x)return a.every(c,
-d);var e=true;i(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.some=function(a,c,d){c=c||b.identity;if(y&&a.some===y)return a.some(c,d);var e=false;i(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(m&&a.indexOf===m)return a.indexOf(c)!=-1;var d=false;i(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=function(a,c){return b.map(a,
-function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};i(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};i(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(e,f,g){return{value:e,
-criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return o.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?o.call(a,0,c):a[0]};b.rest=function(a,
-c,d){return o.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.filter(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.filter(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,e)))d.push(e);return d})};
-b.intersect=function(a){var c=b.rest(arguments);return b.filter(b.uniq(a),function(d){return b.every(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(m&&a.indexOf===m)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(z&&a.lastIndexOf===z)return a.lastIndexOf(c);for(var d=a.length;d--;)if(a[d]===
-c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||{},d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);i(c,function(d){a[d]=b.bind(a[d],a)});return a};b.delay=function(a,
-c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=E||function(a){if(b.isArray(a))return b.range(0,a.length);var c=[];for(var d in a)p.call(a,
-d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.filter(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a){i(b.rest(arguments),function(c){for(var d in c)a[d]=c[d]});return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
-if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!(f in c)||!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){if(b.isArray(a))return a.length===
-0;for(var c in a)if(p.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=l||function(a){return!!(a&&a.concat&&a.unshift&&!a.callee)};b.isArguments=function(a){return a&&a.callee};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return a===+a||D.call(a)==="[object Number]"};b.isBoolean=function(a){return a===true||a===false};b.isDate=function(a){return!!(a&&
-a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){n._=A;return this};b.identity=function(a){return a};b.times=function(a,c,d){for(var e=0;e<a;e++)c.call(d,e)};b.breakLoop=function(){throw r;};b.mixin=function(a){i(b.functions(a),function(c){F(c,b[c]=a[c])})};
-var G=0;b.uniqueId=function(a){var c=G++;return a?a+c:c};b.templateSettings={start:"<%",end:"%>",interpolate:/<%=(.+?)%>/g};b.template=function(a,c){var d=b.templateSettings,e=new RegExp("'(?=[^"+d.end.substr(0,1)+"]*"+B(d.end)+")","g");a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").replace(e,"\t").split("'").join("\\'").split("\t").join("'").replace(d.interpolate,"',$1,'").split(d.start).join("');").split(d.end).join("p.push('")+
-"');}return p.join('');");return c?a(c):a};b.each=b.forEach;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.select=b.filter;b.all=b.every;b.any=b.some;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var k=function(a){this._wrapped=a},q=function(a,c){return c?b(a).chain():a},F=function(a,c){k.prototype[a]=function(){var d=b.toArray(arguments);C.call(d,this._wrapped);return q(c.apply(b,d),this._chain)}};b.mixin(b);i(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=j[a];
-k.prototype[a]=function(){c.apply(this._wrapped,arguments);return q(this._wrapped,this._chain)}});i(["concat","join","slice"],function(a){var c=j[a];k.prototype[a]=function(){return q(c.apply(this._wrapped,arguments),this._chain)}});k.prototype.chain=function(){this._chain=true;return this};k.prototype.value=function(){return this._wrapped}})();
View
14 modestmaps.js
@@ -1,5 +1,5 @@
/*!
- * Modest Maps JS v0.13.3
+ * Modest Maps JS v0.13.4
* http://modestmaps.com/
*
* Copyright (c) 2010 Stamen Design, All Rights Reserved.
@@ -1521,8 +1521,10 @@ if (!com) {
var ty = center.y + (tile.coord.row - theCoord.row) * tileHeight;
tile.style.left = Math.round(tx) + 'px';
tile.style.top = Math.round(ty) + 'px';
- tile.width = Math.ceil(tileWidth);
- tile.height = Math.ceil(tileHeight);
+ // using style here and not raw width/height for ipad/iphone scaling
+ // see examples/touch/test.html
+ tile.style.width = Math.ceil(tileWidth) + 'px';
+ tile.style.height = Math.ceil(tileHeight) + 'px';
// log last-touched-time of currently cached tiles
this.recentTilesById[tile.id].lastTouchedTime = now;
}
@@ -1579,8 +1581,10 @@ if (!com) {
var ty = ((theMap.dimensions.y/2) + (tile.coord.row - theCoord.row) * theMap.provider.tileHeight * scale);
tile.style.left = Math.round(tx) + 'px';
tile.style.top = Math.round(ty) + 'px';
- tile.width = Math.ceil(theMap.provider.tileWidth * scale);
- tile.height = Math.ceil(theMap.provider.tileHeight * scale);
+ // using style here and not raw width/height for ipad/iphone scaling
+ // see examples/touch/test.html
+ tile.style.width = Math.ceil(theMap.provider.tileWidth * scale) + 'px';
+ tile.style.height = Math.ceil(theMap.provider.tileHeight * scale) + 'px';
// request a lazy redraw of all layers
// this will remove tiles that were only visible
View
4 modestmaps.min.js
@@ -1,5 +1,5 @@
/*
- * Modest Maps JS v0.13.3
+ * Modest Maps JS v0.13.4
* http://modestmaps.com/
*
* Copyright (c) 2010 Stamen Design, All Rights Reserved.
@@ -11,4 +11,4 @@
* See CHANGELOG and http://semver.org/ for more 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.Point.distance=function(e,d){var c=(d.x-e.x);var b=(d.y-e.y);return Math.sqrt(c*c+b*b)};a.Point.interpolate=function(f,e,d){var c=f.x+(e.x-f.x)*d;var b=f.y+(e.y-f.y)*d;return new a.Point(c,b)};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.Location.distance=function(i,h,b){if(!b){b=6378000}var o=Math.PI/180,g=i.lat*o,n=i.lon*o,f=h.lat*o,m=h.lon*o,l=Math.cos(g)*Math.cos(n)*Math.cos(f)*Math.cos(m),k=Math.cos(g)*Math.sin(n)*Math.cos(f)*Math.sin(m),j=Math.sin(g)*Math.sin(f);return Math.acos(l+k+j)*b};a.Location.interpolate=function(i,g,m){var s=Math.PI/180,k=i.lat*s,n=i.lon*s,j=g.lat*s,l=g.lon*s;var o=2*Math.asin(Math.sqrt(Math.pow(Math.sin((k-j)/2),2)+Math.cos(k)*Math.cos(j)*Math.pow(Math.sin((n-l)/2),2)));var t=Math.atan2(Math.sin(n-l)*Math.cos(j),Math.cos(k)*Math.sin(j)-Math.sin(k)*Math.cos(j)*Math.cos(n-l))/-(Math.PI/180);t=t<0?360+t:t;var e=Math.sin((1-m)*o)/Math.sin(o);var b=Math.sin(m*o)/Math.sin(o);var r=e*Math.cos(k)*Math.cos(n)+b*Math.cos(j)*Math.cos(l);var q=e*Math.cos(k)*Math.sin(n)+b*Math.cos(j)*Math.sin(l);var p=e*Math.sin(k)+b*Math.sin(j);var c=Math.atan2(p,Math.sqrt(Math.pow(r,2)+Math.pow(q,2)));var h=Math.atan2(q,r);return new a.Location(c/s,h/s)};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(0,a.deriveTransformation(-Math.PI,Math.PI,0,0,Math.PI,Math.PI,1,0,-Math.PI,-Math.PI,0,1)),tileWidth:256,tileHeight:256,topLeftOuterLimit:new a.Coordinate(0,0,0),bottomRightInnerLimit:new a.Coordinate(1,1,0).zoomTo(18),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)},outerLimits:function(){return[this.topLeftOuterLimit.copy(),this.bottomRightInnerLimit.copy()]},sourceCoordinate:function(g){var b=this.topLeftOuterLimit.zoomTo(g.zoom);var d=this.bottomRightInnerLimit.zoomTo(g.zoom);var c=d.row-b.row;if(g.row<0|g.row>=c){return null}var f=d.column-b.column;var e=g.column%f;while(e<0){e+=f}return new a.Coordinate(g.row,e,g.zoom)}};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.CallbackManager=function(b,d){this.owner=b;this.callbacks={};for(var c=0;c<d.length;c++){this.callbacks[d[c]]=[]}};a.CallbackManager.prototype={owner:null,callbacks:null,addCallback:function(b,c){if(typeof(c)=="function"&&this.callbacks[b]){this.callbacks[b].push(c)}},removeCallback:function(e,f){if(typeof(f)=="function"&&this.callbacks[e]){var c=this.callbacks[e],b=c.length;for(var d=0;d<b;d++){if(c[d]===f){c.splice(d,1);break}}}},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.owner,c)}catch(f){}}}}};a.RequestManager=function(b){this.loadingBay=document.createElement("div");this.loadingBay.id=b.id+"-loading-bay";this.loadingBay.style.display="none";b.appendChild(this.loadingBay);this.requestsById={};this.openRequestCount=0;this.maxOpenRequests=4;this.requestQueue=[];this.callbackManager=new a.CallbackManager(this,["requestcomplete"])};a.RequestManager.prototype={loadingBay:null,requestsById:null,requestQueue:null,openRequestCount:null,maxOpenRequests:null,callbackManager:null,addCallback:function(b,c){this.callbackManager.addCallback(b,c)},removeCallback:function(b,c){this.callbackManager.removeCallback(b,c)},dispatchCallback:function(c,b){this.callbackManager.dispatchCallback(c,b)},clear:function(){this.clearExcept({})},clearExcept:function(f){for(var d=0;d<this.requestQueue.length;d++){var e=this.requestQueue[d];if(e&&!(e.key in f)){this.requestQueue[d]=null}}var b=this.loadingBay.getElementsByTagName("img");for(var d=b.length-1;d>=0;d--){var c=b[d];if(!(c.id in f)){this.loadingBay.removeChild(c);this.openRequestCount--;c.src=c.coord=c.onload=c.onerror=null}}for(var g in this.requestsById){if(this.requestsById.hasOwnProperty(g)){if(!(g in f)){var e=this.requestsById[g];delete this.requestsById[g];if(e!=null){e=e.key=e.coord=e.url=null}}}}},hasRequest:function(b){return(b in this.requestsById)},requestTile:function(c,e,b){if(!(c in this.requestsById)){var d={key:c,coord:e.copy(),url:b};this.requestsById[c]=d;if(b){this.requestQueue.push(d)}}},processQueue:function(d){if(d&&this.requestQueue.length>8){this.requestQueue.sort(d)}while(this.openRequestCount<this.maxOpenRequests&&this.requestQueue.length>0){var c=this.requestQueue.pop();if(c){this.openRequestCount++;var b=document.createElement("img");b.id=c.key;b.style.position="absolute";b.coord=c.coord;this.loadingBay.appendChild(b);b.onload=b.onerror=this.getLoadComplete();b.src=c.url;c=c.key=c.coord=c.url=null}}},_loadComplete:null,getLoadComplete:function(){if(!this._loadComplete){var b=this;this._loadComplete=function(d){d=d||window.event;var c=d.srcElement||d.target;c.onload=c.onerror=null;b.loadingBay.removeChild(c);b.openRequestCount--;delete b.requestsById[c.id];if(c.complete||(c.readyState&&c.readyState=="complete")){b.dispatchCallback("requestcomplete",c)}else{c.src=null}b.processQueue()}}return this._loadComplete},};a.Map=function(k,j,b,c){if(typeof k=="string"){k=document.getElementById(k)}this.parent=k;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 l=this.parent.offsetWidth;var f=this.parent.offsetHeight;if(!l){l=640;this.parent.style.width=l+"px"}if(!f){f=480;this.parent.style.height=f+"px"}b=new a.Point(l,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.requestManager=new a.RequestManager(this.parent);this.requestManager.addCallback("requestcomplete",this.getTileComplete());this.layers={};this.layerParent=document.createElement("div");this.layerParent.id=this.parent.id+"-layers";this.layerParent.style.cssText="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; margin: 0; padding: 0; z-index: 0";this.parent.appendChild(this.layerParent);this.coordinate=new a.Coordinate(0.5,0.5,0);this.setProvider(j);this.callbackManager=new a.CallbackManager(this,["zoomed","panned","centered","extentset","resized","drawn"])};a.Map.prototype={parent:null,provider:null,dimensions:null,coordinate:null,tiles:null,layers:null,layerParent:null,requestManager:null,tileCacheSize:null,maxTileCacheSize:null,recentTiles:null,recentTilesById:null,callbackManager:null,eventHandlers:null,toString:function(){return"Map(#"+this.parent.id+")"},addCallback:function(b,c){this.callbackManager.addCallback(b,c)},removeCallback:function(b,c){this.callbackManager.removeCallback(b,c)},dispatchCallback:function(c,b){this.callbackManager.dispatchCallback(c,b)},zoomBy:function(b){this.coordinate=this.coordinate.zoomBy(b);this.draw();this.dispatchCallback("zoomed",b)},zoomIn:function(){this.zoomBy(1)},zoomOut:function(){this.zoomBy(-1)},setZoom:function(b){this.zoomBy(b-this.coordinate.zoom)},zoomByAbout:function(c,b){var e=this.pointLocation(b);this.zoomBy(c);var d=this.locationPoint(e);this.panBy(b.x-d.x,b.y-d.y)},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(parseFloat(c)||0);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);d=Math.min(d,this.provider.outerLimits()[1].zoom);d=Math.max(d,this.provider.outerLimits()[0].zoom);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){this.requestManager.clear();for(var b in this.layers){if(this.layers.hasOwnProperty(b)){var c=this.layers[b];while(c.firstChild){c.removeChild(c.firstChild)}}}}this.tiles={};this.tileCacheSize=0;this.maxTileCacheSize=64;this.recentTiles=[];this.recentTilesById={};this.provider=d;if(!e){this.draw()}},enforceLimits:function(e){e=e.copy();var c=this.provider.outerLimits();if(c){var d=c[0].zoom;var b=c[1].zoom;if(e.zoom<d){e=e.zoomTo(d)}else{if(e.zoom>b){e=e.zoomTo(b)}}}return e},draw:function(){this.coordinate=this.enforceLimits(this.coordinate);var o=Math.round(this.coordinate.zoom);var u=this.pointCoordinate(new a.Point(0,0)).zoomTo(o).container();var s=this.pointCoordinate(this.dimensions).zoomTo(o).container().right().down();var h=0;if(h){u=u.left(h).up(h);s=s.right(h).down(h)}var D={};var l=this.createOrGetLayer(u.zoom);var e=u.copy();for(e.column=u.column;e.column<=s.column;e.column+=1){for(e.row=u.row;e.row<=s.row;e.row+=1){var m=e.toKey();D[m]=true;if(m in this.tiles){var G=this.tiles[m];if(G.parentNode!=l){l.appendChild(G)}}else{if(!this.requestManager.hasRequest(m)){var n=this.provider.getTileUrl(e);this.requestManager.requestTile(m,e,n)}var q=false;for(var r=1;r<=5;r++){var t=e.zoomBy(-r).container();var x=t.toKey();if(x in this.tiles){D[x]=true;q=true;break}}if(!q){var k=e.zoomBy(1);D[k.toKey()]=true;k.column+=1;D[k.toKey()]=true;k.row+=1;D[k.toKey()]=true;k.column-=1;D[k.toKey()]=true}}}}for(var H in this.layers){if(this.layers.hasOwnProperty(H)){var d=parseInt(H,10);if(d>=u.zoom-5&&d<u.zoom+2){continue}var F=this.layers[H];F.style.display="none";var C=F.getElementsByTagName("img");for(var v=C.length-1;v>=0;v--){F.removeChild(C[v])}}}var f=new Date().getTime();var y=u.zoom-5;var g=u.zoom+2;for(var w=y;w<g;w++){var F=this.layers[w];if(!F){continue}var E=1;var c=this.coordinate.copy();if(F.childNodes.length>0){F.style.display="block";E=Math.pow(2,this.coordinate.zoom-w);c=c.zoomTo(w)}else{F.style.display="none"}var b=this.provider.tileWidth*E;var p=this.provider.tileHeight*E;var A=new a.Point(this.dimensions.x/2,this.dimensions.y/2);var C=F.getElementsByTagName("img");for(var v=C.length-1;v>=0;v--){var G=C[v];if(!D[G.id]){F.removeChild(G)}else{var B=A.x+(G.coord.column-c.column)*b;var z=A.y+(G.coord.row-c.row)*p;G.style.left=Math.round(B)+"px";G.style.top=Math.round(z)+"px";G.width=Math.ceil(b);G.height=Math.ceil(p);this.recentTilesById[G.id].lastTouchedTime=f}}}this.requestManager.clearExcept(D);this.requestManager.processQueue(this.getCenterDistanceCompare());this.checkCache();this.dispatchCallback("drawn")},_tileComplete:null,getTileComplete:function(){if(!this._tileComplete){var b=this;this._tileComplete=function(g,h){b.tiles[h.id]=h;b.tileCacheSize++;var e={id:h.id,lastTouchedTime:new Date().getTime()};b.recentTilesById[h.id]=e;b.recentTiles.push(e);var i=b.layers[h.coord.zoom];i.appendChild(h);var f=b.coordinate.zoomTo(h.coord.zoom);var j=Math.pow(2,b.coordinate.zoom-h.coord.zoom);var d=((b.dimensions.x/2)+(h.coord.column-f.column)*b.provider.tileWidth*j);var c=((b.dimensions.y/2)+(h.coord.row-f.row)*b.provider.tileHeight*j);h.style.left=Math.round(d)+"px";h.style.top=Math.round(c)+"px";h.width=Math.ceil(b.provider.tileWidth*j);h.height=Math.ceil(b.provider.tileHeight*j);b.requestRedraw()}}return this._tileComplete},_redrawTimer:undefined,requestRedraw:function(){if(!this._redrawTimer){this._redrawTimer=setTimeout(this.getRedraw(),1000)}},_redraw:null,getRedraw:function(){if(!this._redraw){var b=this;this._redraw=function(){b.draw();b._redrawTimer=0}}return this._redraw},createOrGetLayer:function(c){if(c in this.layers){return this.layers[c]}var b=document.createElement("div");b.id=this.parent.id+"-zoom-"+c;b.style.cssText=this.layerParent.style.cssText;b.style.zIndex=c;this.layerParent.appendChild(b);this.layers[c]=b;return b},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?-1:g.lastTouchedTime>h.lastTouchedTime?1:0})}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--}}},getCenterDistanceCompare:function(){var b=this.coordinate.zoomTo(Math.round(this.coordinate.zoom));return function(e,d){if(e&&d){var g=e.coord;var f=d.coord;if(g.zoom==f.zoom){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}else{return g.zoom<f.zoom?1:g.zoom>f.zoom?-1:0}}return e?1:d?-1:0}}}})(com.modestmaps);
+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.Point.distance=function(e,d){var c=(d.x-e.x);var b=(d.y-e.y);return Math.sqrt(c*c+b*b)};a.Point.interpolate=function(f,e,d){var c=f.x+(e.x-f.x)*d;var b=f.y+(e.y-f.y)*d;return new a.Point(c,b)};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.Location.distance=function(i,h,b){if(!b){b=6378000}var o=Math.PI/180,g=i.lat*o,n=i.lon*o,f=h.lat*o,m=h.lon*o,l=Math.cos(g)*Math.cos(n)*Math.cos(f)*Math.cos(m),k=Math.cos(g)*Math.sin(n)*Math.cos(f)*Math.sin(m),j=Math.sin(g)*Math.sin(f);return Math.acos(l+k+j)*b};a.Location.interpolate=function(i,g,m){var s=Math.PI/180,k=i.lat*s,n=i.lon*s,j=g.lat*s,l=g.lon*s;var o=2*Math.asin(Math.sqrt(Math.pow(Math.sin((k-j)/2),2)+Math.cos(k)*Math.cos(j)*Math.pow(Math.sin((n-l)/2),2)));var t=Math.atan2(Math.sin(n-l)*Math.cos(j),Math.cos(k)*Math.sin(j)-Math.sin(k)*Math.cos(j)*Math.cos(n-l))/-(Math.PI/180);t=t<0?360+t:t;var e=Math.sin((1-m)*o)/Math.sin(o);var b=Math.sin(m*o)/Math.sin(o);var r=e*Math.cos(k)*Math.cos(n)+b*Math.cos(j)*Math.cos(l);var q=e*Math.cos(k)*Math.sin(n)+b*Math.cos(j)*Math.sin(l);var p=e*Math.sin(k)+b*Math.sin(j);var c=Math.atan2(p,Math.sqrt(Math.pow(r,2)+Math.pow(q,2)));var h=Math.atan2(q,r);return new a.Location(c/s,h/s)};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(0,a.deriveTransformation(-Math.PI,Math.PI,0,0,Math.PI,Math.PI,1,0,-Math.PI,-Math.PI,0,1)),tileWidth:256,tileHeight:256,topLeftOuterLimit:new a.Coordinate(0,0,0),bottomRightInnerLimit:new a.Coordinate(1,1,0).zoomTo(18),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)},outerLimits:function(){return[this.topLeftOuterLimit.copy(),this.bottomRightInnerLimit.copy()]},sourceCoordinate:function(g){var b=this.topLeftOuterLimit.zoomTo(g.zoom);var d=this.bottomRightInnerLimit.zoomTo(g.zoom);var c=d.row-b.row;if(g.row<0|g.row>=c){return null}var f=d.column-b.column;var e=g.column%f;while(e<0){e+=f}return new a.Coordinate(g.row,e,g.zoom)}};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.CallbackManager=function(b,d){this.owner=b;this.callbacks={};for(var c=0;c<d.length;c++){this.callbacks[d[c]]=[]}};a.CallbackManager.prototype={owner:null,callbacks:null,addCallback:function(b,c){if(typeof(c)=="function"&&this.callbacks[b]){this.callbacks[b].push(c)}},removeCallback:function(e,f){if(typeof(f)=="function"&&this.callbacks[e]){var c=this.callbacks[e],b=c.length;for(var d=0;d<b;d++){if(c[d]===f){c.splice(d,1);break}}}},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.owner,c)}catch(f){}}}}};a.RequestManager=function(b){this.loadingBay=document.createElement("div");this.loadingBay.id=b.id+"-loading-bay";this.loadingBay.style.display="none";b.appendChild(this.loadingBay);this.requestsById={};this.openRequestCount=0;this.maxOpenRequests=4;this.requestQueue=[];this.callbackManager=new a.CallbackManager(this,["requestcomplete"])};a.RequestManager.prototype={loadingBay:null,requestsById:null,requestQueue:null,openRequestCount:null,maxOpenRequests:null,callbackManager:null,addCallback:function(b,c){this.callbackManager.addCallback(b,c)},removeCallback:function(b,c){this.callbackManager.removeCallback(b,c)},dispatchCallback:function(c,b){this.callbackManager.dispatchCallback(c,b)},clear:function(){this.clearExcept({})},clearExcept:function(f){for(var d=0;d<this.requestQueue.length;d++){var e=this.requestQueue[d];if(e&&!(e.key in f)){this.requestQueue[d]=null}}var b=this.loadingBay.getElementsByTagName("img");for(var d=b.length-1;d>=0;d--){var c=b[d];if(!(c.id in f)){this.loadingBay.removeChild(c);this.openRequestCount--;c.src=c.coord=c.onload=c.onerror=null}}for(var g in this.requestsById){if(this.requestsById.hasOwnProperty(g)){if(!(g in f)){var e=this.requestsById[g];delete this.requestsById[g];if(e!=null){e=e.key=e.coord=e.url=null}}}}},hasRequest:function(b){return(b in this.requestsById)},requestTile:function(c,e,b){if(!(c in this.requestsById)){var d={key:c,coord:e.copy(),url:b};this.requestsById[c]=d;if(b){this.requestQueue.push(d)}}},processQueue:function(d){if(d&&this.requestQueue.length>8){this.requestQueue.sort(d)}while(this.openRequestCount<this.maxOpenRequests&&this.requestQueue.length>0){var c=this.requestQueue.pop();if(c){this.openRequestCount++;var b=document.createElement("img");b.id=c.key;b.style.position="absolute";b.coord=c.coord;this.loadingBay.appendChild(b);b.onload=b.onerror=this.getLoadComplete();b.src=c.url;c=c.key=c.coord=c.url=null}}},_loadComplete:null,getLoadComplete:function(){if(!this._loadComplete){var b=this;this._loadComplete=function(d){d=d||window.event;var c=d.srcElement||d.target;c.onload=c.onerror=null;b.loadingBay.removeChild(c);b.openRequestCount--;delete b.requestsById[c.id];if(c.complete||(c.readyState&&c.readyState=="complete")){b.dispatchCallback("requestcomplete",c)}else{c.src=null}b.processQueue()}}return this._loadComplete},};a.Map=function(k,j,b,c){if(typeof k=="string"){k=document.getElementById(k)}this.parent=k;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 l=this.parent.offsetWidth;var f=this.parent.offsetHeight;if(!l){l=640;this.parent.style.width=l+"px"}if(!f){f=480;this.parent.style.height=f+"px"}b=new a.Point(l,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.requestManager=new a.RequestManager(this.parent);this.requestManager.addCallback("requestcomplete",this.getTileComplete());this.layers={};this.layerParent=document.createElement("div");this.layerParent.id=this.parent.id+"-layers";this.layerParent.style.cssText="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; margin: 0; padding: 0; z-index: 0";this.parent.appendChild(this.layerParent);this.coordinate=new a.Coordinate(0.5,0.5,0);this.setProvider(j);this.callbackManager=new a.CallbackManager(this,["zoomed","panned","centered","extentset","resized","drawn"])};a.Map.prototype={parent:null,provider:null,dimensions:null,coordinate:null,tiles:null,layers:null,layerParent:null,requestManager:null,tileCacheSize:null,maxTileCacheSize:null,recentTiles:null,recentTilesById:null,callbackManager:null,eventHandlers:null,toString:function(){return"Map(#"+this.parent.id+")"},addCallback:function(b,c){this.callbackManager.addCallback(b,c)},removeCallback:function(b,c){this.callbackManager.removeCallback(b,c)},dispatchCallback:function(c,b){this.callbackManager.dispatchCallback(c,b)},zoomBy:function(b){this.coordinate=this.coordinate.zoomBy(b);this.draw();this.dispatchCallback("zoomed",b)},zoomIn:function(){this.zoomBy(1)},zoomOut:function(){this.zoomBy(-1)},setZoom:function(b){this.zoomBy(b-this.coordinate.zoom)},zoomByAbout:function(c,b){var e=this.pointLocation(b);this.zoomBy(c);var d=this.locationPoint(e);this.panBy(b.x-d.x,b.y-d.y)},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(parseFloat(c)||0);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);d=Math.min(d,this.provider.outerLimits()[1].zoom);d=Math.max(d,this.provider.outerLimits()[0].zoom);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){this.requestManager.clear();for(var b in this.layers){if(this.layers.hasOwnProperty(b)){var c=this.layers[b];while(c.firstChild){c.removeChild(c.firstChild)}}}}this.tiles={};this.tileCacheSize=0;this.maxTileCacheSize=64;this.recentTiles=[];this.recentTilesById={};this.provider=d;if(!e){this.draw()}},enforceLimits:function(e){e=e.copy();var c=this.provider.outerLimits();if(c){var d=c[0].zoom;var b=c[1].zoom;if(e.zoom<d){e=e.zoomTo(d)}else{if(e.zoom>b){e=e.zoomTo(b)}}}return e},draw:function(){this.coordinate=this.enforceLimits(this.coordinate);var o=Math.round(this.coordinate.zoom);var u=this.pointCoordinate(new a.Point(0,0)).zoomTo(o).container();var s=this.pointCoordinate(this.dimensions).zoomTo(o).container().right().down();var h=0;if(h){u=u.left(h).up(h);s=s.right(h).down(h)}var D={};var l=this.createOrGetLayer(u.zoom);var e=u.copy();for(e.column=u.column;e.column<=s.column;e.column+=1){for(e.row=u.row;e.row<=s.row;e.row+=1){var m=e.toKey();D[m]=true;if(m in this.tiles){var G=this.tiles[m];if(G.parentNode!=l){l.appendChild(G)}}else{if(!this.requestManager.hasRequest(m)){var n=this.provider.getTileUrl(e);this.requestManager.requestTile(m,e,n)}var q=false;for(var r=1;r<=5;r++){var t=e.zoomBy(-r).container();var x=t.toKey();if(x in this.tiles){D[x]=true;q=true;break}}if(!q){var k=e.zoomBy(1);D[k.toKey()]=true;k.column+=1;D[k.toKey()]=true;k.row+=1;D[k.toKey()]=true;k.column-=1;D[k.toKey()]=true}}}}for(var H in this.layers){if(this.layers.hasOwnProperty(H)){var d=parseInt(H,10);if(d>=u.zoom-5&&d<u.zoom+2){continue}var F=this.layers[H];F.style.display="none";var C=F.getElementsByTagName("img");for(var v=C.length-1;v>=0;v--){F.removeChild(C[v])}}}var f=new Date().getTime();var y=u.zoom-5;var g=u.zoom+2;for(var w=y;w<g;w++){var F=this.layers[w];if(!F){continue}var E=1;var c=this.coordinate.copy();if(F.childNodes.length>0){F.style.display="block";E=Math.pow(2,this.coordinate.zoom-w);c=c.zoomTo(w)}else{F.style.display="none"}var b=this.provider.tileWidth*E;var p=this.provider.tileHeight*E;var A=new a.Point(this.dimensions.x/2,this.dimensions.y/2);var C=F.getElementsByTagName("img");for(var v=C.length-1;v>=0;v--){var G=C[v];if(!D[G.id]){F.removeChild(G)}else{var B=A.x+(G.coord.column-c.column)*b;var z=A.y+(G.coord.row-c.row)*p;G.style.left=Math.round(B)+"px";G.style.top=Math.round(z)+"px";G.style.width=Math.ceil(b)+"px";G.style.height=Math.ceil(p)+"px";this.recentTilesById[G.id].lastTouchedTime=f}}}this.requestManager.clearExcept(D);this.requestManager.processQueue(this.getCenterDistanceCompare());this.checkCache();this.dispatchCallback("drawn")},_tileComplete:null,getTileComplete:function(){if(!this._tileComplete){var b=this;this._tileComplete=function(g,h){b.tiles[h.id]=h;b.tileCacheSize++;var e={id:h.id,lastTouchedTime:new Date().getTime()};b.recentTilesById[h.id]=e;b.recentTiles.push(e);var i=b.layers[h.coord.zoom];i.appendChild(h);var f=b.coordinate.zoomTo(h.coord.zoom);var j=Math.pow(2,b.coordinate.zoom-h.coord.zoom);var d=((b.dimensions.x/2)+(h.coord.column-f.column)*b.provider.tileWidth*j);var c=((b.dimensions.y/2)+(h.coord.row-f.row)*b.provider.tileHeight*j);h.style.left=Math.round(d)+"px";h.style.top=Math.round(c)+"px";h.style.width=Math.ceil(b.provider.tileWidth*j)+"px";h.style.height=Math.ceil(b.provider.tileHeight*j)+"px";b.requestRedraw()}}return this._tileComplete},_redrawTimer:undefined,requestRedraw:function(){if(!this._redrawTimer){this._redrawTimer=setTimeout(this.getRedraw(),1000)}},_redraw:null,getRedraw:function(){if(!this._redraw){var b=this;this._redraw=function(){b.draw();b._redrawTimer=0}}return this._redraw},createOrGetLayer:function(c){if(c in this.layers){return this.layers[c]}var b=document.createElement("div");b.id=this.parent.id+"-zoom-"+c;b.style.cssText=this.layerParent.style.cssText;b.style.zIndex=c;this.layerParent.appendChild(b);this.layers[c]=b;return b},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?-1:g.lastTouchedTime>h.lastTouchedTime?1:0})}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--}}},getCenterDistanceCompare:function(){var b=this.coordinate.zoomTo(Math.round(this.coordinate.zoom));return function(e,d){if(e&&d){var g=e.coord;var f=d.coord;if(g.zoom==f.zoom){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}else{return g.zoom<f.zoom?1:g.zoom>f.zoom?-1:0}}return e?1:d?-1:0}}}})(com.modestmaps);

0 comments on commit 7618308

Please sign in to comment.
Something went wrong with that request. Please try again.