.surface containing the rendering
+ container: null, // root-level group within the surface
+ backdrop: null, // coloured backdrop (MapCSS canvas element)
+ connection: null, // data store
+ controller: null, // UI controller
+ uis: {},
- constructor: function(obj) {
- // summary: The main map display, containing the individual sprites (UIs) for each entity.
- // obj: Object An object containing .lat, .lon, .scale, .div (the name of the
to be used),
- // .connection, .width (px) and .height (px) properties.
+ tilegroup: null, // group within container for adding bitmap tiles
+ tiles: {}, // index of tile objects
+ tilebaseURL: 'http://ecn.t0.tiles.virtualearth.net/tiles/a$quadkey.jpeg?g=587&mkt=en-gb&n=z', // Bing imagery URL
- this.mapwidth = obj.width ? obj.width : 800;
- this.mapheight = obj.height ? obj.height : 400;
+ dragging: false, // current drag state
+ dragged: false, // was most recent click a drag?
+ dragx: NaN, // click co-ordinates at previously recorded drag event
+ dragy: NaN, // |
+ startdragx: NaN, // click co-ordinates at start of drag
+ startdragy: NaN, // |
+ dragtime: NaN, // timestamp of mouseup (compared to stop resulting click from firing)
+ dragconnect: null, // event listener for endDrag
- // Initialise variables
- this.uis = {};
- this.div=document.getElementById(obj.div);
- this.surface=Gfx.createSurface(obj.div, this.mapwidth, this.mapheight);
- this.backdrop=this.surface.createRect({
- x: 0,
- y: 0,
- width: this.mapwidth,
- height: this.mapheight
- }).setFill(new dojo.Color([255,255,245,1]));
- this.tilegroup = this.surface.createGroup();
- this.container = this.surface.createGroup();
- this.connection = obj.connection;
- this.zoom = obj.zoom ? obj.zoom : 17;
- this.baselon = obj.lon;
- this.baselat = obj.lat;
- this.baselatp = this.lat2latp(obj.lat);
- this._setScaleFactor();
- this.updateCoordsFromViewportPosition();
+ containerx: 0, // screen co-ordinates of container
+ containery: 0, // |
+ centrelat: NaN, // lat/long and bounding box of map
+ centrelon: NaN, // |
+ extent: {}, // |
+ mapheight: NaN, // size of map object in pixels
+ mapwidth: NaN, // |
- // Cache the margin box, since this is expensive.
- this.marginBox = domGeom.getMarginBox(this.div);
+ layers: null, // array-like object of Groups, one for each OSM layer
+ minlayer: -5, // minimum OSM layer supported
+ maxlayer: 5, // maximum OSM layer supported
- // Initialise layers
- this.layers={};
- for (var l=this.minlayer; l<=this.maxlayer; l++) {
- var r=this.container.createGroup();
- this.layers[l]={
- root: r,
- fill: r.createGroup(),
- casing: r.createGroup(),
- stroke: r.createGroup(),
- text: r.createGroup(),
- hit: r.createGroup()
- };
+ elastic: null, // Group for drawing elastic band
+ ruleset: null, // map style
+
+ setController:function(controller) {
+ // summary: Set the controller that will handle events on the map (e.g. mouse clicks).
+ this.controller = controller;
+ },
+
+ _moveToPosition:function(group, position) {
+ // summary: Supplementary method for dojox.gfx.
+ // This should ideally be core Dojo stuff: see http://bugs.dojotoolkit.org/ticket/15296
+ var parent=group.getParent();
+ if (!parent) { return; }
+ this._moveChildToPosition(parent,group,position);
+ if (position === group.rawNode.parentNode.childNodes.length) {
+ group.rawNode.parentNode.appendChild(group.rawNode);
+ } else {
+ group.rawNode.parentNode.insertBefore(group.rawNode, group.rawNode.parentNode.childNodes[position]);
+ }
+ },
+
+ _moveChildToPosition: function(parent, child, position) {
+ for (var i = 0; i < parent.children.length; ++i){
+ if (parent.children[i] === child){
+ parent.children.splice(i, 1);
+ parent.children.splice(position, 0, child);
+ break;
}
+ }
+ },
- // Create group for elastic band
- this.elastic = this.container.createGroup();
+ // ----------------------------
+ // Sprite and EntityUI handling
- // Make draggable
- this.backdrop.connect("onmousedown", _.bind(this.startDrag, this));
- this.tilegroup.connect("onmousedown", _.bind(this.startDrag, this));
- this.surface.connect("onclick", _.bind(this.clickSurface, this));
- this.surface.connect("onmousemove", _.bind(this.processMove, this));
- this.surface.connect("onmousedown", _.bind(this._mouseEvent, this));
- this.surface.connect("onmouseup", _.bind(this._mouseEvent, this));
- },
-
- setController:function(controller) {
- // summary: Set the controller that will handle events on the map (e.g. mouse clicks).
- this.controller = controller;
- },
-
- _moveToPosition:function(group, position) {
- // summary: Supplementary method for dojox.gfx.
- // This should ideally be core Dojo stuff: see http://bugs.dojotoolkit.org/ticket/15296
- var parent=group.getParent();
- if (!parent) { return; }
- this._moveChildToPosition(parent,group,position);
- if (position === group.rawNode.parentNode.childNodes.length) {
- group.rawNode.parentNode.appendChild(group.rawNode);
- } else {
- group.rawNode.parentNode.insertBefore(group.rawNode, group.rawNode.parentNode.childNodes[position]);
+ sublayer:function(layer,groupType,sublayer) {
+ // summary: Find the gfx.Group for a given OSM layer and rendering sublayer, creating it
+ // if necessary. Note that sublayers are only implemented for stroke and fill.
+ // groupType: String 'casing','text','hit','stroke', or 'fill'
+ var collection = this.layers[layer][groupType], sub;
+ switch (groupType) {
+ case 'casing':
+ case 'text':
+ case 'hit':
+ return collection;
+ }
+ // Find correct sublayer, inserting if necessary
+ var insertAt=collection.children.length;
+ for (var i = 0; i < collection.children.length; i++) {
+ sub=collection.children[i];
+ if (sub.sublayer==sublayer) { return sub; }
+ else if (sub.sublayer>sublayer) {
+ sub = collection.createGroup();
+ this._moveToPosition(sub,i);
+ sub.sublayer=sublayer;
+ return sub;
}
- },
+ }
+ sub = collection.createGroup().moveToFront();
+ sub.sublayer=sublayer;
+ return sub; // dojox.gfx.Group
+ },
- _moveChildToPosition: function(parent, child, position) {
- for (var i = 0; i < parent.children.length; ++i){
- if (parent.children[i] === child){
- parent.children.splice(i, 1);
- parent.children.splice(position, 0, child);
- break;
- }
+ createUI: function(e, stateClasses) {
+ // summary: Create a UI (sprite) for an entity, assigning any specified state classes
+ // (temporary attributes such as ':hover' or ':selected')
+ if (!this.uis[e.id]) {
+ if (e.entityType === 'node') {
+ this.uis[e.id] = new iD.renderer.NodeUI(e, this, stateClasses);
+ } else if (e.entityType === 'way') {
+ this.uis[e.id] = new iD.renderer.WayUI(e, this, stateClasses);
}
- },
+ } else {
+ this.uis[e.id].setStateClasses(stateClasses).redraw();
+ }
+ },
- // ----------------------------
- // Sprite and EntityUI handling
+ getUI: function(e) {
+ // summary: Return the UI for an entity, if it exists.
+ return this.uis[e.id]; // iD.renderer.EntityUI
+ },
- sublayer:function(layer,groupType,sublayer) {
- // summary: Find the gfx.Group for a given OSM layer and rendering sublayer, creating it
- // if necessary. Note that sublayers are only implemented for stroke and fill.
- // groupType: String 'casing','text','hit','stroke', or 'fill'
- var collection = this.layers[layer][groupType], sub;
- switch (groupType) {
- case 'casing':
- case 'text':
- case 'hit':
- return collection;
- }
- // Find correct sublayer, inserting if necessary
- var insertAt=collection.children.length;
- for (var i = 0; i < collection.children.length; i++) {
- sub=collection.children[i];
- if (sub.sublayer==sublayer) { return sub; }
- else if (sub.sublayer>sublayer) {
- sub = collection.createGroup();
- this._moveToPosition(sub,i);
- sub.sublayer=sublayer;
- return sub;
- }
- }
- sub = collection.createGroup().moveToFront();
- sub.sublayer=sublayer;
- return sub; // dojox.gfx.Group
- },
+ refreshUI: function(e) {
+ // summary: Redraw the UI for an entity.
+ if (this.uis[e.id]) { this.uis[e.id].redraw(); }
+ },
- createUI: function(e, stateClasses) {
- // summary: Create a UI (sprite) for an entity, assigning any specified state classes
- // (temporary attributes such as ':hover' or ':selected')
+ deleteUI: function(e) {
+ // summary: Delete the UI for an entity.
+ if (this.uis[e.id]) {
+ this.uis[e.id].removeSprites();
+ delete this.uis[e.id];
+ }
+ },
+
+ download: function() {
+ // summary: Ask the connection to download data for the current viewport.
+ this.connection.loadFromAPI(this.extent, _.bind(this.updateUIs, this));
+ },
+
+ updateUIs: function() {
+ // summary: Draw/refresh all EntityUIs within the bbox, and remove any others.
+ // redraw: Boolean Should we redraw any UIs that are already present?
+ // remove: Boolean Should we delete any UIs that are no longer in the bbox?
+ var o = this.connection.getObjectsByBbox(this.extent);
+ var touch = _(o.inside).chain()
+ .filter(function(w) { return w.loaded; })
+ .map(_.bind(function(e) {
if (!this.uis[e.id]) {
- if (e.entityType === 'node') {
- this.uis[e.id] = new iD.renderer.NodeUI(e, this, stateClasses);
- } else if (e.entityType === 'way') {
- this.uis[e.id] = new iD.renderer.WayUI(e, this, stateClasses);
- }
+ this.createUI(e);
} else {
- this.uis[e.id].setStateClasses(stateClasses).redraw();
+ this.uis[e.id].redraw();
}
- },
+ return '' + e.id;
+ }, this)).value();
+ _.each(_.difference(_.keys(this.uis), touch), _.bind(function(k) {
+ this.deleteUI(k);
+ }, this));
+ },
- getUI: function(e) {
- // summary: Return the UI for an entity, if it exists.
- return this.uis[e.id]; // iD.renderer.EntityUI
- },
+ // -------------
+ // Zoom handling
- refreshUI: function(e) {
- // summary: Redraw the UI for an entity.
- if (this.uis[e.id]) { this.uis[e.id].redraw(); }
- },
+ zoomIn: function() {
+ // summary: Zoom in by one level (unless maximum reached).
+ return this.setZoom(this.zoom + 1);
+ },
- deleteUI: function(e) {
- // summary: Delete the UI for an entity.
- if (this.uis[e.id]) {
- this.uis[e.id].removeSprites();
- delete this.uis[e.id];
- }
- },
+ zoomOut: function() {
+ // summary: Zoom out by one level (unless minimum reached).
+ this.setZoom(this.zoom - 1);
+ this.download();
+ return this;
+ },
- download: function() {
- // summary: Ask the connection to download data for the current viewport.
- $('#progress').show().addClass('spinner');
- this.connection.loadFromAPI(this.extent, _.bind(this.updateUIs, this));
- },
+ setZoom: function(zoom) {
+ if (zoom < this.MINSCALE || zoom > this.MAXSCALE) return this;
+ // summary: Redraw the map at a new zoom level.
+ this.zoom = zoom;
+ this._setScaleFactor();
+ this._blankTiles();
+ this.setCentre({
+ lat: this.centrelat,
+ lon: this.centrelon
+ });
+ this.updateUIs(true, true);
+ return this;
+ },
- updateUIs: function() {
- // summary: Draw/refresh all EntityUIs within the bbox, and remove any others.
- // redraw: Boolean Should we redraw any UIs that are already present?
- // remove: Boolean Should we delete any UIs that are no longer in the bbox?
- $('#progress').hide().removeClass('spinner');
- var o = this.connection.getObjectsByBbox(this.extent);
- var touch = _(o.inside).chain()
- .filter(function(w) { return w.loaded; })
- .map(_.bind(function(e) {
- if (!this.uis[e.id]) {
- this.createUI(e);
- } else {
- this.uis[e.id].redraw();
- }
- return '' + e.id;
- }, this)).value();
- _.each(_.difference(_.keys(this.uis), touch), _.bind(function(k) {
- this.deleteUI(k);
- }, this));
- },
+ _setScaleFactor: function() {
+ // summary: Calculate the scaling factor for this zoom level.
+ this.zoomfactor = this.MASTERSCALE/Math.pow(2, 13 - this.zoom);
+ },
- // -------------
- // Zoom handling
+ // ----------------------
+ // Elastic band redrawing
- zoomIn: function() {
- // summary: Zoom in by one level (unless maximum reached).
- return this.setZoom(this.zoom + 1);
- },
+ clearElastic: function() {
+ // summary: Remove the elastic band used to draw new ways.
+ this.elastic.clear();
+ },
- zoomOut: function() {
- // summary: Zoom out by one level (unless minimum reached).
- this.setZoom(this.zoom - 1);
- this.download();
- return this;
- },
+ drawElastic: function(x1,y1,x2,y2) {
+ // summary: Draw the elastic band (for new ways) between two points.
+ this.elastic.clear();
+ // **** Next line is SVG-specific
+ this.elastic.rawNode.setAttribute("pointer-events","none");
+ this.elastic.createPolyline( [{ x:x1, y:y1 }, { x:x2, y:y2 }] ).setStroke( {
+ color: [0, 0, 0, 1],
+ style: 'Solid',
+ width: 1
+ });
+ },
- setZoom: function(zoom) {
- if (zoom < this.MINSCALE || zoom > this.MAXSCALE) return this;
- // summary: Redraw the map at a new zoom level.
- this.zoom = zoom;
- this._setScaleFactor();
- this._blankTiles();
- this.setCentre({
- lat: this.centrelat,
- lon: this.centrelon
- });
- this.updateUIs(true, true);
- return this;
- },
+ // -------------
+ // Tile handling
+ // ** FIXME: see docs
+ loadTiles: function() {
+ // summary: Load all tiles for the current viewport. This is a bare-bones function
+ // at present: it needs configurable URLs (not just Bing), attribution/logo
+ // support, and to be 'nudgable' (i.e. adjust the offset).
+ var tl = this.locationCoord({
+ lat: this.extent.north,
+ lon: this.extent.west
+ }, this.zoom),
+ br = this.locationCoord({
+ lat: this.extent.south,
+ lon: this.extent.east
+ }, this.zoom),
+ tileKeys = _.keys(this.tiles),
+ seen = [],
+ coord = { z: this.zoom };
- _setScaleFactor: function() {
- // summary: Calculate the scaling factor for this zoom level.
- this.zoomfactor = this.MASTERSCALE/Math.pow(2, 13 - this.zoom);
- },
-
- // ----------------------
- // Elastic band redrawing
-
- clearElastic: function() {
- // summary: Remove the elastic band used to draw new ways.
- this.elastic.clear();
- },
-
- drawElastic: function(x1,y1,x2,y2) {
- // summary: Draw the elastic band (for new ways) between two points.
- this.elastic.clear();
- // **** Next line is SVG-specific
- this.elastic.rawNode.setAttribute("pointer-events","none");
- this.elastic.createPolyline( [{ x:x1, y:y1 }, { x:x2, y:y2 }] ).setStroke( {
- color: [0, 0, 0, 1],
- style: 'Solid',
- width: 1
- });
- },
-
- // -------------
- // Tile handling
- // ** FIXME: see docs
- loadTiles: function() {
- // summary: Load all tiles for the current viewport. This is a bare-bones function
- // at present: it needs configurable URLs (not just Bing), attribution/logo
- // support, and to be 'nudgable' (i.e. adjust the offset).
- var tl = this.locationCoord({
- lat: this.extent.north,
- lon: this.extent.west
- }, this.zoom),
- br = this.locationCoord({
- lat: this.extent.south,
- lon: this.extent.east
- }, this.zoom),
- tileKeys = _.keys(this.tiles),
- seen = [],
- coord = { z: this.zoom };
-
- for (coord.x = tl.x; coord.x <= br.x; coord.x++) {
- for (coord.y = tl.y; coord.y <= br.y; coord.y++) {
- if (!this._getTile(coord)) {
- this._fetchTile(coord);
- }
- seen.push(iD.Util.tileKey(coord));
+ for (coord.x = tl.x; coord.x <= br.x; coord.x++) {
+ for (coord.y = tl.y; coord.y <= br.y; coord.y++) {
+ if (!this._getTile(coord)) {
+ this._fetchTile(coord);
}
+ seen.push(iD.Util.tileKey(coord));
}
+ }
- _.each(_.without(tileKeys, seen), _.bind(function(key) {
- delete this.tiles[key];
- }, this));
- },
+ _.each(_.without(tileKeys, seen), _.bind(function(key) {
+ delete this.tiles[key];
+ }, this));
+ },
- _fetchTile: function(coord) {
- // summary: Load a tile image at the given tile co-ordinates.
- var t = this.tilegroup.createImage({
- x: Math.floor(this.lon2coord(this.tile2lon(coord.x))),
- y: Math.floor(this.lat2coord(this.tile2lat(coord.y))),
+ _fetchTile: function(coord) {
+ // summary: Load a tile image at the given tile co-ordinates.
+ var t = this.tilegroup.append('image')
+ .attr({
width: 256,
height: 256,
- src: this._tileURL(coord)
+ x: Math.floor(this.lon2coord(this.tile2lon(coord.x))),
+ y: Math.floor(this.lat2coord(this.tile2lat(coord.y))),
+ 'xlink:href': this._tileURL(coord)
});
- this._assignTile(coord, t);
- },
+ this._assignTile(coord, t);
+ },
- _getTile: function(coord) {
- // summary: See if this tile is already loaded.
- return this.tiles[iD.Util.tileKey(coord)];
- },
+ _getTile: function(coord) {
+ // summary: See if this tile is already loaded.
+ return this.tiles[iD.Util.tileKey(coord)];
+ },
- _assignTile: function(coord, t) {
- // summary: Store a reference to the tile so we know it's loaded.
- this.tiles[iD.Util.tileKey(coord)] = t;
- },
+ _assignTile: function(coord, t) {
+ // summary: Store a reference to the tile so we know it's loaded.
+ this.tiles[iD.Util.tileKey(coord)] = t;
+ },
- _tileURL: function(coord) {
- // summary: Calculate the URL for a tile at the given co-ordinates.
- var u = '';
- for (var zoom = coord.z; zoom > 0; zoom--) {
- var byte = 0;
- var mask = 1 << (zoom - 1);
- if ((coord.x & mask) !== 0) byte++;
- if ((coord.y & mask) !== 0) byte += 2;
- u += byte.toString();
+ _tileURL: function(coord) {
+ // summary: Calculate the URL for a tile at the given co-ordinates.
+ var u = '';
+ for (var zoom = coord.z; zoom > 0; zoom--) {
+ var byte = 0;
+ var mask = 1 << (zoom - 1);
+ if ((coord.x & mask) !== 0) byte++;
+ if ((coord.y & mask) !== 0) byte += 2;
+ u += byte.toString();
+ }
+ return this.tilebaseURL
+ .replace('$z', coord.z)
+ .replace('$x', coord.x)
+ .replace('$y', coord.y)
+ .replace('$quadkey', u);
+ },
+
+ _blankTiles: function() {
+ // summary: Unload all tiles and remove from the display.
+ this.tilegroup.clear();
+ this.tiles = {};
+ },
+
+ // -------------------------------------------
+ // Co-ordinate management, dragging and redraw
+
+ startDrag: function(e) {
+ // summary: Start dragging the map in response to a mouse-down.
+ // e: MouseEvent The mouse-down event that triggered it.
+ var srcElement = (e.gfxTarget === this.backdrop) ?
+ e.gfxTarget : e.gfxTarget.parent;
+ Event.stop(e);
+ this.dragging = true;
+ this.dragged = false;
+ this.dragx = this.dragy=NaN;
+ this.startdragx = e.clientX;
+ this.startdragy = e.clientY;
+ this.dragconnect = srcElement.connect("onmouseup", _.bind(this.endDrag, this));
+ },
+
+ endDrag: function(e) {
+ // summary: Stop dragging the map in response to a mouse-up.
+ // e: MouseEvent The mouse-up event that triggered it.
+ Event.stop(e);
+ dojo.disconnect(this.dragconnect);
+ this.dragging=false;
+ this.dragtime=e.timeStamp;
+ this.updateCoordsFromViewportPosition();
+ if (Math.abs(e.clientX - this.startdragx) < 3 &&
+ Math.abs(e.clientY - this.startdragy) < 3) {
+ return;
+ }
+ this.download();
+ },
+
+ processMove: function(e) {
+ // summary: Drag the map to a new origin.
+ // e: MouseEvent The mouse-move event that triggered it.
+ var x = e.clientX;
+ var y = e.clientY;
+ if (this.dragging) {
+ if (this.dragx) {
+ this.containerx += (x - this.dragx);
+ this.containery += (y - this.dragy);
+ this.updateOrigin();
+ this.dragged=true;
}
- return this.tilebaseURL
- .replace('$z', coord.z)
- .replace('$x', coord.x)
- .replace('$y', coord.y)
- .replace('$quadkey', u);
- },
-
- _blankTiles: function() {
- // summary: Unload all tiles and remove from the display.
- this.tilegroup.clear();
- this.tiles = {};
- },
-
- // -------------------------------------------
- // Co-ordinate management, dragging and redraw
-
- startDrag: function(e) {
- // summary: Start dragging the map in response to a mouse-down.
- // e: MouseEvent The mouse-down event that triggered it.
- var srcElement = (e.gfxTarget === this.backdrop) ?
- e.gfxTarget : e.gfxTarget.parent;
- Event.stop(e);
- this.dragging = true;
- this.dragged = false;
- this.dragx = this.dragy=NaN;
- this.startdragx = e.clientX;
- this.startdragy = e.clientY;
- this.dragconnect = srcElement.connect("onmouseup", _.bind(this.endDrag, this));
- },
-
- endDrag: function(e) {
- // summary: Stop dragging the map in response to a mouse-up.
- // e: MouseEvent The mouse-up event that triggered it.
- Event.stop(e);
- dojo.disconnect(this.dragconnect);
- this.dragging=false;
- this.dragtime=e.timeStamp;
- this.updateCoordsFromViewportPosition();
- if (Math.abs(e.clientX - this.startdragx) < 3 &&
- Math.abs(e.clientY - this.startdragy) < 3) {
- return;
- }
- this.download();
- },
-
- processMove: function(e) {
- // summary: Drag the map to a new origin.
- // e: MouseEvent The mouse-move event that triggered it.
- var x = e.clientX;
- var y = e.clientY;
- if (this.dragging) {
- if (this.dragx) {
- this.containerx += (x - this.dragx);
- this.containery += (y - this.dragy);
- this.updateOrigin();
- this.dragged=true;
- }
- this.dragx = x;
- this.dragy = y;
- } else {
- this.controller.entityMouseEvent(e,null);
- }
- },
-
- updateOrigin: function() {
- // summary: Tell Dojo to update the viewport origin.
- this.container.setTransform([Matrix.translate(this.containerx, this.containery)]);
- this.tilegroup.setTransform([Matrix.translate(this.containerx, this.containery)]);
- },
-
- _mouseEvent: function(e) {
- // summary: Catch mouse events on the surface but not the tiles - in other words,
- // on drawn items that don't have their own hitzones, like the fill of a shape.
- if (e.type=='mousedown') { this.startDrag(e); }
- // ** FIXME: we may want to reinstate this at some point...
- // this.controller.entityMouseEvent(e,null);
- },
-
- updateCoordsFromViewportPosition: function(e) {
- // summary: Update centre and bbox from the current viewport origin.
- this._updateCoords(this.containerx, this.containery);
- },
-
- setCentre: function(loc) {
- // summary: Update centre and bbox to a specified lat/lon.
- var coord = this.locationCoord(loc, this.zoom);
- this._updateCoords(
- -coord.x - this.mapwidth / 2,
- -coord.y - this.mapheight / 2);
- return this;
- },
-
- setCenter: function(loc) { this.setCentre(loc); },
-
- _updateCoords:function(x, y) {
- // summary: Set centre and bbox.
- this.containerx = x;
- this.containery = y;
- this.updateOrigin();
- this.centrelon = this.coord2lon(-x + this.mapwidth/2);
- this.centrelat = this.coord2lat(-y + this.mapheight/2);
-
- this.extent = {
- north: this.coord2lat(-y),
- south: this.coord2lat(-y + this.mapheight),
- west: this.coord2lon(-x),
- east: this.coord2lon(-x + this.mapwidth)
- };
-
- this.loadTiles();
- },
-
- clickSurface:function(e) {
- // summary: Handle a click on an empty area of the map.
- if (this.dragged && e.timeStamp==this.dragtime) { return; }
+ this.dragx = x;
+ this.dragy = y;
+ } else {
this.controller.entityMouseEvent(e,null);
- },
+ }
+ },
- // -----------------------
- // Co-ordinate conversions
+ updateOrigin: function() {
+ // summary: Tell Dojo to update the viewport origin.
+ // this.container.setTransform([Matrix.translate(this.containerx, this.containery)]);
+ // this.tilegroup.setTransform([Matrix.translate(this.containerx, this.containery)]);
+ },
- latp2coord:function(a) { return -(a-this.baselatp)*this.zoomfactor; },
- coord2latp:function(a) { return a/-this.zoomfactor+this.baselatp; },
- lon2coord:function(a) { return (a-this.baselon)*this.zoomfactor; },
- coord2lon:function(a) { return a/this.zoomfactor+this.baselon; },
- lon2screen:function(a) { return this.lon2coord(a) + this.marginBox.l + this.containerx; },
+ _mouseEvent: function(e) {
+ // summary: Catch mouse events on the surface but not the tiles - in other words,
+ // on drawn items that don't have their own hitzones, like the fill of a shape.
+ if (e.type=='mousedown') { this.startDrag(e); }
+ // ** FIXME: we may want to reinstate this at some point...
+ // this.controller.entityMouseEvent(e,null);
+ },
- lat2latp:function(a) { return 180/Math.PI * Math.log(Math.tan(Math.PI/4+a*(Math.PI/180)/2)); },
- latp2lat:function(a) { return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2); },
- lat2coord:function(a) { return -(this.lat2latp(a)-this.baselatp)*this.zoomfactor; },
- coord2lat:function(a) { return this.latp2lat(a/-this.zoomfactor+this.baselatp); },
- lat2screen:function(a) { return this.lat2coord(a) + this.marginBox.t + this.containery; },
+ updateCoordsFromViewportPosition: function(e) {
+ // summary: Update centre and bbox from the current viewport origin.
+ this._updateCoords(this.containerx, this.containery);
+ },
- locationCoord: function(ll, z) {
- var z2 = Math.pow(2, z), d2r = Math.PI / 180;
- return {
- z: z,
- x: Math.floor((ll.lon + 180) / 360 * z2),
- y: Math.floor((1 - Math.log(Math.tan(ll.lat * d2r) +
- 1 / Math.cos(ll.lat * d2r)) / Math.PI) / 2 * z2)
- };
- },
- lon2tile:function(a) { return (Math.floor((a+180)/360*Math.pow(2,this.zoom))); },
- lat2tile:function(a) { return (Math.floor((1-Math.log(Math.tan(a*Math.PI/180) + 1/Math.cos(a*Math.PI/180))/Math.PI)/2 *Math.pow(2,this.zoom))); },
- tile2lon:function(a) { return (a/Math.pow(2,this.zoom)*360-180); },
- tile2lat:function(a) {
- var n=Math.PI-2*Math.PI*a/Math.pow(2,this.zoom);
- return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
- },
+ setCentre: function(loc) {
+ // summary: Update centre and bbox to a specified lat/lon.
+ var coord = this.locationCoord(loc, this.zoom);
+ this._updateCoords(
+ -coord.x - this.mapwidth / 2,
+ -coord.y - this.mapheight / 2);
+ return this;
+ },
- // Turn event co-ordinates into map co-ordinates
+ setCenter: function(loc) { this.setCentre(loc); },
- mouseX: function(e) { return e.clientX - this.marginBox.l - this.containerx; },
- mouseY: function(e) { return e.clientY - this.marginBox.t - this.containery; }
- });
+ _updateCoords:function(x, y) {
+ // summary: Set centre and bbox.
+ this.containerx = x;
+ this.containery = y;
+ this.updateOrigin();
+ this.centrelon = this.coord2lon(-x + this.mapwidth/2);
+ this.centrelat = this.coord2lat(-y + this.mapheight/2);
- // ----------------------------------------------------------------------
- // End of module
-});
+ this.extent = {
+ north: this.coord2lat(-y),
+ south: this.coord2lat(-y + this.mapheight),
+ west: this.coord2lon(-x),
+ east: this.coord2lon(-x + this.mapwidth)
+ };
+
+ this.loadTiles();
+ },
+
+ clickSurface:function(e) {
+ // summary: Handle a click on an empty area of the map.
+ if (this.dragged && e.timeStamp==this.dragtime) { return; }
+ this.controller.entityMouseEvent(e,null);
+ },
+
+ // -----------------------
+ // Co-ordinate conversions
+
+ latp2coord:function(a) { return -(a-this.baselatp)*this.zoomfactor; },
+ coord2latp:function(a) { return a/-this.zoomfactor+this.baselatp; },
+ lon2coord:function(a) { return (a-this.baselon)*this.zoomfactor; },
+ coord2lon:function(a) { return a/this.zoomfactor+this.baselon; },
+ lon2screen:function(a) { return this.lon2coord(a) + this.marginBox.l + this.containerx; },
+
+ lat2latp:function(a) { return 180/Math.PI * Math.log(Math.tan(Math.PI/4+a*(Math.PI/180)/2)); },
+ latp2lat:function(a) { return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2); },
+ lat2coord:function(a) { return -(this.lat2latp(a)-this.baselatp)*this.zoomfactor; },
+ coord2lat:function(a) { return this.latp2lat(a/-this.zoomfactor+this.baselatp); },
+ lat2screen:function(a) { return this.lat2coord(a) + this.marginBox.t + this.containery; },
+
+ locationCoord: function(ll, z) {
+ var z2 = Math.pow(2, z), d2r = Math.PI / 180;
+ return {
+ z: z,
+ x: Math.floor((ll.lon + 180) / 360 * z2),
+ y: Math.floor((1 - Math.log(Math.tan(ll.lat * d2r) +
+ 1 / Math.cos(ll.lat * d2r)) / Math.PI) / 2 * z2)
+ };
+ },
+ lon2tile:function(a) { return (Math.floor((a+180)/360*Math.pow(2,this.zoom))); },
+ lat2tile:function(a) { return (Math.floor((1-Math.log(Math.tan(a*Math.PI/180) + 1/Math.cos(a*Math.PI/180))/Math.PI)/2 *Math.pow(2,this.zoom))); },
+ tile2lon:function(a) { return (a/Math.pow(2,this.zoom)*360-180); },
+ tile2lat:function(a) {
+ var n=Math.PI-2*Math.PI*a/Math.pow(2,this.zoom);
+ return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
+ },
+
+ // Turn event co-ordinates into map co-ordinates
+
+ mouseX: function(e) { return e.clientX - this.marginBox.l - this.containerx; },
+ mouseY: function(e) { return e.clientY - this.marginBox.t - this.containery; }
+};
diff --git a/js/iD/renderer/NodeUI.js b/js/iD/renderer/NodeUI.js
index 163fcacbb..cda3ace40 100755
--- a/js/iD/renderer/NodeUI.js
+++ b/js/iD/renderer/NodeUI.js
@@ -1,107 +1,94 @@
-// iD/renderer/NodeUI.js
-// NodeUI classes for iD
+iD.renderer.NodeUI = function() {};
+iD.renderer.NodeUI.prototype = {
+ getEnhancedTags:function() {
+ var tags=this.inherited(arguments);
+ if (!this.entity.entity.hasParentWays()) { tags[':poi']='yes'; }
+ // add junction and dupe
+ return tags;
+ },
+ redraw:function() {
+ // summary: Draw the object (mostly icons) and add hitzone sprites.
+ var node = this.entity;
+ this.removeSprites();
-define(['dojo/_base/declare','dojox/gfx/_base','iD/renderer/EntityUI'],
- function(declare, g) {
+ // Tags, position and styleList
+ var x = Math.floor(this.map.lon2coord(this.entity.lon));
+ var y = Math.floor(this.map.latp2coord(this.entity.latp));
+ var tags = this.getEnhancedTags();
+ this.refreshStyleList(tags);
-// ----------------------------------------------------------------------
-// NodeUI class
-
-declare("iD.renderer.NodeUI", [iD.renderer.EntityUI], {
- constructor:function() {
- // summary: A UI (rendering) representing a node.
- this.redraw();
- },
- getEnhancedTags:function() {
- var tags=this.inherited(arguments);
- if (!this.entity.entity.hasParentWays()) { tags[':poi']='yes'; }
- // add junction and dupe
- return tags;
- },
- redraw:function() {
- // summary: Draw the object (mostly icons) and add hitzone sprites.
- var node = this.entity;
- this.removeSprites();
-
- // Tags, position and styleList
- var x = Math.floor(this.map.lon2coord(this.entity.lon));
- var y = Math.floor(this.map.latp2coord(this.entity.latp));
- var tags = this.getEnhancedTags();
- this.refreshStyleList(tags);
-
- // Iterate through each subpart, drawing any styles on that layer
- var drawn = false;
- var s, p, t, w, h;
- for (i = 0; i < this.styleList.subparts.length; i++) {
- var subpart=this.styleList.subparts[i];
- p = this.styleList.pointStyles[subpart];
- if (!p || !p.drawn()) { continue; }
- s = this.styleList.shapeStyles[subpart];
- t = this.styleList.textStyles[subpart];
- w = p.icon_width ? p.icon_width : 16;
- h = p.icon_height ? p.icon_height: w;
+ // Iterate through each subpart, drawing any styles on that layer
+ var drawn = false;
+ var s, p, t, w, h;
+ for (i = 0; i < this.styleList.subparts.length; i++) {
+ var subpart=this.styleList.subparts[i];
+ p = this.styleList.pointStyles[subpart];
+ if (!p || !p.drawn()) { continue; }
+ s = this.styleList.shapeStyles[subpart];
+ t = this.styleList.textStyles[subpart];
+ w = p.icon_width ? p.icon_width : 16;
+ h = p.icon_height ? p.icon_height: w;
// Draw icon
var shape;
- if (p.icon_image === 'square') shape = this.targetGroup('stroke', p.sublayer)
+ if (p.icon_image === 'square') {
+ shape = this.targetGroup('stroke', p.sublayer)
.createRect({
x: x-w/2,
y: y-h/2,
width: w,
height: h
});
- else if (p.icon_image === 'circle') shape = this.targetGroup('stroke', p.sublayer)
- .createCircle({
- cx: x,
- cy: y,
- r: w
- });
- else shape = this.targetGroup('stroke',p.sublayer)
- .createImage({
- width: w,
- height: h,
- x: x-w/2,
- y: y-h/2,
- src: p.icon_image
- });
- if (p.icon_image === 'square' || p.icon_image === 'circle') {
- shape.setStroke(s.shapeStrokeStyler()).setFill(s.shapeFillStyler());
- }
- this.recordSprite(shape);
-
- // Add text label
- // Add hit-zone
- var hit;
- if (p.icon_image === 'circle') {
- hit = this.targetGroup('hit').createCircle({
- cx: x,
- cy: y,
- r: w
- });
+ } else if (p.icon_image === 'circle') {
+ shape = this.targetGroup('stroke', p.sublayer)
+ .createCircle({
+ cx: x,
+ cy: y,
+ r: w
+ });
} else {
- hit = this.targetGroup('hit').createRect({
- x: x-w/2,
- y: y-h/2,
- width: w,
- height: h
- });
+ shape = this.targetGroup('stroke',p.sublayer)
+ .createImage({
+ width: w,
+ height: h,
+ x: x-w/2,
+ y: y-h/2,
+ src: p.icon_image
+ });
+ if (p.icon_image === 'square' || p.icon_image === 'circle') {
+ shape.setStroke(s.shapeStrokeStyler()).setFill(s.shapeFillStyler());
+ }
+ this.recordSprite(shape);
+
+ // Add text label
+ // Add hit-zone
+ var hit;
+ if (p.icon_image === 'circle') {
+ hit = this.targetGroup('hit').createCircle({
+ cx: x,
+ cy: y,
+ r: w
+ });
+ } else {
+ hit = this.targetGroup('hit').createRect({
+ x: x-w/2,
+ y: y-h/2,
+ width: w,
+ height: h
+ });
+ }
+ hit.setFill([0,1,0,0]).setStroke({
+ width:2,
+ color:[0,0,0,0]
+ });
+ this.recordSprite(hit);
+ hit.source = this;
+ hit.connect("onclick", _.bind(this.entityMouseEvent, this));
+ hit.connect("onmousedown", _.bind(this.entityMouseEvent, this));
+ hit.connect("onmouseup", _.bind(this.entityMouseEvent, this));
+ hit.connect("onmouseenter", _.bind(this.entityMouseEvent, this));
+ hit.connect("onmouseleave", _.bind(this.entityMouseEvent, this));
}
- hit.setFill([0,1,0,0]).setStroke({
- width:2,
- color:[0,0,0,0]
- });
- this.recordSprite(hit);
- hit.source = this;
- hit.connect("onclick", _.bind(this.entityMouseEvent, this));
- hit.connect("onmousedown", _.bind(this.entityMouseEvent, this));
- hit.connect("onmouseup", _.bind(this.entityMouseEvent, this));
- hit.connect("onmouseenter", _.bind(this.entityMouseEvent, this));
- hit.connect("onmouseleave", _.bind(this.entityMouseEvent, this));
- }
- }
-});
-
-
-// ----------------------------------------------------------------------
-// End of module
-});
+ }
+ }
+};
diff --git a/js/iD/renderer/WayUI.js b/js/iD/renderer/WayUI.js
index 3ae0def54..8c5b75491 100755
--- a/js/iD/renderer/WayUI.js
+++ b/js/iD/renderer/WayUI.js
@@ -1,4 +1,3 @@
-// iD/renderer/WayUI.js
// WayUI classes for iD
// **** TODO:
// multipolygon support - http://mail.dojotoolkit.org/pipermail/dojo-interest/2011-January/052042.html
@@ -7,16 +6,11 @@
// fill images
// opacity
-define(['dojo/_base/declare','iD/renderer/EntityUI'], function(declare) {
-
// ----------------------------------------------------------------------
// WayUI class
+iD.renderer.WayUI = function() {};
-declare("iD.renderer.WayUI", [iD.renderer.EntityUI], {
- constructor: function() {
- // summary: A UI (rendering) representing a way.
- this.redraw();
- },
+iD.renderer.WayUI.prototype = {
getEnhancedTags: function() {
var tags = this.inherited(arguments);
if (this.entity.isClosed()) { tags[':area']='yes'; }
@@ -139,8 +133,4 @@ declare("iD.renderer.WayUI", [iD.renderer.EntityUI], {
entityMouseEvent:function(event) {
this.inherited(arguments);
}
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
+};
diff --git a/js/iD/renderer/renderer.js b/js/iD/renderer/renderer.js
new file mode 100644
index 000000000..593d9bb7a
--- /dev/null
+++ b/js/iD/renderer/renderer.js
@@ -0,0 +1 @@
+iD.renderer = {};
diff --git a/js/iD/styleparser/Condition.js b/js/iD/styleparser/Condition.js
index 6c509b6f4..bcbae09b5 100755
--- a/js/iD/styleparser/Condition.js
+++ b/js/iD/styleparser/Condition.js
@@ -1,11 +1,8 @@
-// iD/styleparser/Condition.js
-
-define(['dojo/_base/declare'], function(declare){
-
// ----------------------------------------------------------------------
// Condition base class
-declare("iD.styleparser.Condition", null, {
+iD.styleparser.Condition = function() {};
+iD.styleparser.Condition.prototype = {
type: '', // eq/ne/regex etc.
params: [], // what to test against
@@ -38,8 +35,4 @@ declare("iD.styleparser.Condition", null, {
toString:function() {
return "["+this.type+": "+this.params+"]";
}
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
+};
diff --git a/js/iD/styleparser/Rule.js b/js/iD/styleparser/Rule.js
index 5fffb211f..c2a4d5ea1 100755
--- a/js/iD/styleparser/Rule.js
+++ b/js/iD/styleparser/Rule.js
@@ -1,55 +1,47 @@
-// iD/styleparser/Rule.js
-
-define(['dojo/_base/declare','dojo/_base/array'], function(declare,array){
-
// ----------------------------------------------------------------------
// Rule class
+iD.styleparser.Rule = function() {};
+iD.styleparser.Rule.prototype = {
-declare("iD.styleparser.Rule", null, {
+ conditions: [], // the Conditions to be evaluated for the Rule to be fulfilled
+ isAnd: true, // do all Conditions need to be true for the Rule to be fulfilled? (Always =true for MapCSS)
+ minZoom: 0, // minimum zoom level at which the Rule is fulfilled
+ maxZoom: 255, // maximum zoom level at which the Rule is fulfilled
+ subject: '', // entity type to which the Rule applies: 'way', 'node', 'relation', 'area' (closed way) or 'line' (unclosed way)
- conditions: [], // the Conditions to be evaluated for the Rule to be fulfilled
- isAnd: true, // do all Conditions need to be true for the Rule to be fulfilled? (Always =true for MapCSS)
- minZoom: 0, // minimum zoom level at which the Rule is fulfilled
- maxZoom: 255, // maximum zoom level at which the Rule is fulfilled
- subject: '', // entity type to which the Rule applies: 'way', 'node', 'relation', 'area' (closed way) or 'line' (unclosed way)
-
- constructor: function(_subject) {
- // summary: A MapCSS selector. Contains a list of Conditions; the entity type to which the selector applies;
- // and the zoom levels at which it is true. way[waterway=river][boat=yes] would be parsed into one Rule.
- // The selectors and declaration together form a StyleChooser.
- this.subject=_subject;
- this.conditions=[];
- },
-
- addCondition: function(_condition) {
- // summary: Add a condition to this rule.
- this.conditions.push(_condition);
- },
+ constructor: function(_subject) {
+ // summary: A MapCSS selector. Contains a list of Conditions; the entity type to which the selector applies;
+ // and the zoom levels at which it is true. way[waterway=river][boat=yes] would be parsed into one Rule.
+ // The selectors and declaration together form a StyleChooser.
+ this.subject=_subject;
+ this.conditions=[];
+ },
- test: function(entity,tags,zoom) {
- // summary: Evaluate the Rule on the given entity, tags and zoom level.
- // returns: true if the Rule passes, false if the conditions aren't fulfilled.
- if ((this.subject !== '') && (entity.entityType !== this.subject)) {
+ addCondition: function(_condition) {
+ // summary: Add a condition to this rule.
+ this.conditions.push(_condition);
+ },
+
+ test: function(entity,tags,zoom) {
+ // summary: Evaluate the Rule on the given entity, tags and zoom level.
+ // returns: true if the Rule passes, false if the conditions aren't fulfilled.
+ if ((this.subject !== '') && (entity.entityType !== this.subject)) {
return false;
}
- if (zoom
this.maxZoom) { return false; }
+ if (zoomthis.maxZoom) { return false; }
- var v=true; var i=0; var isAnd=this.isAnd;
- array.forEach(this.conditions, function(condition) {
- var r=condition.test(tags);
- if (i === 0) { v=r; }
- else if (isAnd) { v=v && r; }
- else { v = v || r; }
- i++;
- });
- return v;
- },
+ var v=true; var i=0; var isAnd=this.isAnd;
+ array.forEach(this.conditions, function(condition) {
+ var r=condition.test(tags);
+ if (i === 0) { v=r; }
+ else if (isAnd) { v=v && r; }
+ else { v = v || r; }
+ i++;
+ });
+ return v;
+ },
- toString:function() {
- return this.subject+" z"+this.minZoom+"-"+this.maxZoom+": "+this.conditions;
- }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
+ toString:function() {
+ return this.subject+" z"+this.minZoom+"-"+this.maxZoom+": "+this.conditions;
+ }
+};
diff --git a/js/iD/styleparser/RuleChain.js b/js/iD/styleparser/RuleChain.js
index 96b1658c0..20a2bca3a 100755
--- a/js/iD/styleparser/RuleChain.js
+++ b/js/iD/styleparser/RuleChain.js
@@ -1,81 +1,72 @@
-// iD/styleparser/RuleChain.js
-
-define(['dojo/_base/declare','iD/styleparser/Rule'], function(declare){
-
// ----------------------------------------------------------------------
// RuleChain base class
// In contrast to Halcyon, note that length() is a function, not a getter property
/** A descendant list of MapCSS selectors (Rules).
- For example,
- relation[type=route] way[highway=primary]
- ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
- first Rule second Rule
- |------------|---------|
- |
- one RuleChain
+ For example,
+ relation[type=route] way[highway=primary]
+ ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
+ first Rule second Rule
+ |------------|---------|
+ |
+ one RuleChain
*/
-declare("iD.styleparser.RuleChain", null, {
+iD.styleparser.RuleChain = function() { };
+iD.styleparser.RuleChain.prototype = {
- rules:[], // list of Rules
- subpart: 'default', // subpart name, as in way[highway=primary]::centreline
-
- constructor:function() {
- // summary: A descendant list of MapCSS selectors (Rules).
- this.rules=[];
- },
+ rules:[], // list of Rules
+ subpart: 'default', // subpart name, as in way[highway=primary]::centreline
- // Functions to define the RuleChain
+ // Functions to define the RuleChain
+ addRule:function(_subject) {
+ this.rules.push(new iD.styleparser.Rule(_subject));
+ },
- addRule:function(_subject) {
- this.rules.push(new iD.styleparser.Rule(_subject));
- },
+ addConditionToLast:function(_condition) {
+ this.rules[this.rules.length-1].addCondition(_condition);
+ },
- addConditionToLast:function(_condition) {
- this.rules[this.rules.length-1].addCondition(_condition);
- },
+ addZoomToLast:function(z1,z2) {
+ this.rules[this.rules.length-1].minZoom=z1;
+ this.rules[this.rules.length-1].maxZoom=z2;
+ },
- addZoomToLast:function(z1,z2) {
- this.rules[this.rules.length-1].minZoom=z1;
- this.rules[this.rules.length-1].maxZoom=z2;
- },
-
- length:function() {
- return this.rules.length;
- },
-
- setSubpart:function(subpart) {
- this.subpart = subpart || 'default';
- },
+ length:function() {
+ return this.rules.length;
+ },
- // Test a ruleChain
- // - run a set of tests in the chain
- // works backwards from at position "pos" in array, or -1 for the last
- // separate tags object is required in case they've been dynamically retagged
- // - if they fail, return false
- // - if they succeed, and it's the last in the chain, return happily
- // - if they succeed, and there's more in the chain, rerun this for each parent until success
+ setSubpart:function(subpart) {
+ this.subpart = subpart || 'default';
+ },
- test: function(pos, entity, tags, zoom) {
- // summary: Test a rule chain by running all the tests in reverse order.
- if (this.rules.length === 0) { return false; }
- if (pos==-1) { pos=this.rules.length-1; }
+ // Test a ruleChain
+ // - run a set of tests in the chain
+ // works backwards from at position "pos" in array, or -1 for the last
+ // separate tags object is required in case they've been dynamically retagged
+ // - if they fail, return false
+ // - if they succeed, and it's the last in the chain, return happily
+ // - if they succeed, and there's more in the chain, rerun this for each parent until success
- var r = this.rules[pos];
- if (!r.test(entity, tags, zoom)) { return false; }
- if (pos === 0) { return true; }
+ test: function(pos, entity, tags, zoom) {
+ // summary: Test a rule chain by running all the tests in reverse order.
+ if (this.rules.length === 0) { return false; }
+ if (pos==-1) { pos=this.rules.length-1; }
- var o = entity.entity.parentObjects();
- for (var i = 0; i < o.length; i++) {
- var p=o[i];
- if (this.test(pos-1, p, p.tags, zoom)) { return true; }
- }
- return false;
- }
+ var r = this.rules[pos];
+ if (!r.test(entity, tags, zoom)) { return false; }
+ if (pos === 0) { return true; }
+
+ var o = entity.entity.parentObjects();
+ for (var i = 0; i < o.length; i++) {
+ var p=o[i];
+ if (this.test(pos-1, p, p.tags, zoom)) { return true; }
+ }
+ return false;
+ }
});
// ----------------------------------------------------------------------
diff --git a/js/iD/styleparser/RuleSet.js b/js/iD/styleparser/RuleSet.js
index f2277d0be..25caeff6c 100755
--- a/js/iD/styleparser/RuleSet.js
+++ b/js/iD/styleparser/RuleSet.js
@@ -1,173 +1,168 @@
-// iD/styleparser/RuleSet.js
-
-define(['dojo/_base/xhr','dojo/_base/lang','dojo/_base/declare','dojo/_base/array','iD/styleparser/Style','iD/styleparser/StyleChooser','iD/styleparser/Condition','iD/styleparser/StyleList'], function(xhr,lang,declare,array){
-
-// ----------------------------------------------------------------------
// RuleSet base class
// needs to cope with nested CSS files
// doesn't do untagged nodes optimisation
-declare("iD.styleparser.RuleSet", null, {
+iD.styleparser.RuleSet = function() {};
- choosers: [], // list of StyleChoosers
- callback: null,
+iD.styleparser.RuleSet.prototype = {
- constructor: function() {
- // summary: An entire stylesheet in parsed form.
- this.choosers = [];
- },
+ choosers: [], // list of StyleChoosers
+ callback: null,
- registerCallback: function(callback) {
- // summary: Set a callback function to be called when the CSS is loaded and parsed.
- this.callback = callback;
- },
+ registerCallback: function(callback) {
+ // summary: Set a callback function to be called when the CSS is loaded and parsed.
+ this.callback = callback;
+ },
- getStyles: function(entity, tags, zoom) {
- // summary: Find the styles for a given entity.
- var sl=new iD.styleparser.StyleList();
- for (var i in this.choosers) {
- this.choosers[i].updateStyles(entity, tags, sl, zoom);
- }
- return sl; // iD.styleparser.StyleList
- },
+ getStyles: function(entity, tags, zoom) {
+ // summary: Find the styles for a given entity.
+ var sl=new iD.styleparser.StyleList();
+ for (var i in this.choosers) {
+ this.choosers[i].updateStyles(entity, tags, sl, zoom);
+ }
+ return sl; // iD.styleparser.StyleList
+ },
- loadFromCSS:function(url) {
- // summary: Load a MapCSS file from a URL, then throw it at the parser when it's loaded.
- xhr.get({ url: url, load: lang.hitch(this, "parseCSS") });
- },
+ loadFromCSS:function(url) {
+ // summary: Load a MapCSS file from a URL, then throw it at the parser when it's loaded.
+ $.ajax({
+ url: url,
+ load: _.bind(this.parseCSS, this)
+ });
+ },
- parseCSS:function(css) {
- // summary: Parse a CSS document into a set of StyleChoosers.
- var previous=0; // what was the previous CSS word?
- var sc = new iD.styleparser.StyleChooser(); // currently being assembled
- this.choosers = [];
- css = css.replace(/[\r\n]/g,""); // strip linebreaks because JavaScript doesn't have the /s modifier
+ parseCSS:function(css) {
+ // summary: Parse a CSS document into a set of StyleChoosers.
+ var previous=0; // what was the previous CSS word?
+ var sc = new iD.styleparser.StyleChooser(); // currently being assembled
+ this.choosers = [];
+ css = css.replace(/[\r\n]/g,""); // strip linebreaks because JavaScript doesn't have the /s modifier
- var o = {};
- while (css.length>0) {
+ var o = {};
+ while (css.length>0) {
- // CSS comment
- if ((o=this.COMMENT.exec(css))) {
- css=css.replace(this.COMMENT,'');
+ // CSS comment
+ if ((o=this.COMMENT.exec(css))) {
+ css=css.replace(this.COMMENT,'');
- // Whitespace (probably only at beginning of file)
- } else if ((o=this.WHITESPACE.exec(css))) {
- css=css.replace(this.WHITESPACE,'');
+ // Whitespace (probably only at beginning of file)
+ } else if ((o=this.WHITESPACE.exec(css))) {
+ css=css.replace(this.WHITESPACE,'');
- // Class - .motorway, .builtup, :hover
- } else if ((o=this.CLASS.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
+ // Class - .motorway, .builtup, :hover
+ } else if ((o=this.CLASS.exec(css))) {
+ if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- css=css.replace(this.CLASS,'');
- sc.currentChain().addConditionToLast(new iD.styleparser.Condition('set',o[1]));
- previous=this.oCONDITION;
+ css=css.replace(this.CLASS,'');
+ sc.currentChain().addConditionToLast(new iD.styleparser.Condition('set',o[1]));
+ previous=this.oCONDITION;
- // Not class - !.motorway, !.builtup, !:hover
- } else if ((o=this.NOT_CLASS.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
+ // Not class - !.motorway, !.builtup, !:hover
+ } else if ((o=this.NOT_CLASS.exec(css))) {
+ if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- css=css.replace(this.NOT_CLASS,'');
- sc.currentChain().addConditionToLast(new iD.styleparser.Condition('unset',o[1]));
- previous=this.oCONDITION;
+ css=css.replace(this.NOT_CLASS,'');
+ sc.currentChain().addConditionToLast(new iD.styleparser.Condition('unset',o[1]));
+ previous=this.oCONDITION;
- // Zoom
- } else if ((o=this.ZOOM.exec(css))) {
- if (previous!=this.oOBJECT && previous!=this.oCONDITION) { sc.currentChain().addRule(); }
+ // Zoom
+ } else if ((o=this.ZOOM.exec(css))) {
+ if (previous!=this.oOBJECT && previous!=this.oCONDITION) { sc.currentChain().addRule(); }
- css=css.replace(this.ZOOM,'');
- var z=parseZoom(o[1]);
- sc.currentChain().addZoomToLast(z[0],z[1]);
- sc.zoomSpecific=true;
- previous=this.oZOOM;
+ css=css.replace(this.ZOOM,'');
+ var z=parseZoom(o[1]);
+ sc.currentChain().addZoomToLast(z[0],z[1]);
+ sc.zoomSpecific=true;
+ previous=this.oZOOM;
- // Grouping - just a comma
- } else if ((o=this.GROUP.exec(css))) {
- css=css.replace(this.GROUP,'');
- sc.newRuleChain();
- previous=this.oGROUP;
+ // Grouping - just a comma
+ } else if ((o=this.GROUP.exec(css))) {
+ css=css.replace(this.GROUP,'');
+ sc.newRuleChain();
+ previous=this.oGROUP;
- // Condition - [highway=primary]
- } else if ((o=this.CONDITION.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- if (previous!=this.oOBJECT && previous!=this.oZOOM && previous!=this.oCONDITION) { sc.currentChain().addRule(); }
- css=css.replace(this.CONDITION,'');
- sc.currentChain().addConditionToLast(this.parseCondition(o[1]));
- previous=this.oCONDITION;
+ // Condition - [highway=primary]
+ } else if ((o=this.CONDITION.exec(css))) {
+ if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
+ if (previous!=this.oOBJECT && previous!=this.oZOOM && previous!=this.oCONDITION) { sc.currentChain().addRule(); }
+ css=css.replace(this.CONDITION,'');
+ sc.currentChain().addConditionToLast(this.parseCondition(o[1]));
+ previous=this.oCONDITION;
- // Object - way, node, relation
- } else if ((o=this.OBJECT.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
+ // Object - way, node, relation
+ } else if ((o=this.OBJECT.exec(css))) {
+ if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- css=css.replace(this.OBJECT,'');
- sc.currentChain().addRule(o[1]);
- previous=this.oOBJECT;
+ css=css.replace(this.OBJECT,'');
+ sc.currentChain().addRule(o[1]);
+ previous=this.oOBJECT;
- // Subpart - ::centreline
- } else if ((o=this.SUBPART.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- css=css.replace(this.SUBPART,'');
- sc.currentChain().setSubpart(o[1]);
- previous=this.oSUBPART;
+ // Subpart - ::centreline
+ } else if ((o=this.SUBPART.exec(css))) {
+ if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
+ css=css.replace(this.SUBPART,'');
+ sc.currentChain().setSubpart(o[1]);
+ previous=this.oSUBPART;
- // Declaration - {...}
- } else if ((o=this.DECLARATION.exec(css))) {
- css=css.replace(this.DECLARATION,'');
- sc.addStyles(this.parseDeclaration(o[1]));
- previous=this.oDECLARATION;
-
- // Unknown pattern
- } else if ((o=this.UNKNOWN.exec(css))) {
- css=css.replace(this.UNKNOWN,'');
- // console.log("unknown: "+o[1]);
+ // Declaration - {...}
+ } else if ((o=this.DECLARATION.exec(css))) {
+ css=css.replace(this.DECLARATION,'');
+ sc.addStyles(this.parseDeclaration(o[1]));
+ previous=this.oDECLARATION;
- } else {
- // console.log("choked on "+css);
- return;
- }
- }
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- if (this.callback) { this.callback(); }
- },
+ // Unknown pattern
+ } else if ((o=this.UNKNOWN.exec(css))) {
+ css=css.replace(this.UNKNOWN,'');
+ // console.log("unknown: "+o[1]);
- saveChooser:function(sc) {
- this.choosers.push(sc);
- },
-
- parseDeclaration:function(s) {
- var styles=[];
- var t={};
- var o={};
- var k, v;
+ } else {
+ // console.log("choked on "+css);
+ return;
+ }
+ }
+ if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
+ if (this.callback) { this.callback(); }
+ },
- // Create styles
- var ss = new iD.styleparser.ShapeStyle();
- var ps = new iD.styleparser.PointStyle();
- var ts = new iD.styleparser.TextStyle();
- var hs = new iD.styleparser.ShieldStyle();
- var xs = new iD.styleparser.InstructionStyle();
+ saveChooser:function(sc) {
+ this.choosers.push(sc);
+ },
- var r=s.split(';');
- var isEval={};
- for (var i in r) {
- var a=r[i];
- if ((o=this.ASSIGNMENT_EVAL.exec(a))) { k=o[1].replace(this.DASH,'_'); t[k]=o[2]; isEval[k]=true; }
- else if ((o=this.ASSIGNMENT.exec(a))) { k=o[1].replace(this.DASH,'_'); t[k]=o[2]; }
- else if ((o=this.SET_TAG_EVAL.exec(a))) { } // xs.addSetTag(o[1],this.saveEval(o[2]));
- else if ((o=this.SET_TAG.exec(a))) { xs.addSetTag(o[1],o[2]); }
- else if ((o=this.SET_TAG_TRUE.exec(a))) { xs.addSetTag(o[1],true); }
- else if ((o=this.EXIT.exec(a))) { xs.setPropertyFromString('breaker',true); }
- }
+ parseDeclaration:function(s) {
+ var styles=[];
+ var t={};
+ var o={};
+ var k, v;
- // Find sublayer
- var sub=5;
- if (t['z_index']) { sub=Number(t['z_index']); delete t['z_index']; }
- ss.sublayer=ps.sublayer=ts.sublayer=hs.sublayer=sub;
- xs.sublayer=10;
+ // Create styles
+ var ss = new iD.styleparser.ShapeStyle();
+ var ps = new iD.styleparser.PointStyle();
+ var ts = new iD.styleparser.TextStyle();
+ var hs = new iD.styleparser.ShieldStyle();
+ var xs = new iD.styleparser.InstructionStyle();
- // Find "interactive" property - it's true unless explicitly set false
- var inter=true;
- if (t['interactive']) { inter=t['interactive'].match(this.FALSE) ? false : true; delete t['interactive']; }
- ss.interactive=ps.interactive=ts.interactive=hs.interactive=xs.interactive=inter;
+ var r=s.split(';');
+ var isEval={};
+ for (var i in r) {
+ var a=r[i];
+ if ((o=this.ASSIGNMENT_EVAL.exec(a))) { k=o[1].replace(this.DASH,'_'); t[k]=o[2]; isEval[k]=true; }
+ else if ((o=this.ASSIGNMENT.exec(a))) { k=o[1].replace(this.DASH,'_'); t[k]=o[2]; }
+ else if ((o=this.SET_TAG_EVAL.exec(a))) { } // xs.addSetTag(o[1],this.saveEval(o[2]));
+ else if ((o=this.SET_TAG.exec(a))) { xs.addSetTag(o[1],o[2]); }
+ else if ((o=this.SET_TAG_TRUE.exec(a))) { xs.addSetTag(o[1],true); }
+ else if ((o=this.EXIT.exec(a))) { xs.setPropertyFromString('breaker',true); }
+ }
+
+ // Find sublayer
+ var sub=5;
+ if (t['z_index']) { sub=Number(t['z_index']); delete t['z_index']; }
+ ss.sublayer=ps.sublayer=ts.sublayer=hs.sublayer=sub;
+ xs.sublayer=10;
+
+ // Find "interactive" property - it's true unless explicitly set false
+ var inter=true;
+ if (t['interactive']) { inter=t['interactive'].match(this.FALSE) ? false : true; delete t['interactive']; }
+ ss.interactive=ps.interactive=ts.interactive=hs.interactive=xs.interactive=inter;
// Munge special values
// (we should stop doing this and do it in the style instead)
@@ -198,261 +193,257 @@ declare("iD.styleparser.RuleSet", null, {
}
// Add each style to list
- if (ss.edited) { styles.push(ss); }
- if (ps.edited) { styles.push(ps); }
- if (ts.edited) { styles.push(ts); }
- if (hs.edited) { styles.push(hs); }
- if (xs.edited) { styles.push(xs); }
- return styles;
- },
+ if (ss.edited) { styles.push(ss); }
+ if (ps.edited) { styles.push(ps); }
+ if (ts.edited) { styles.push(ts); }
+ if (hs.edited) { styles.push(hs); }
+ if (xs.edited) { styles.push(xs); }
+ return styles;
+ },
- parseZoom:function(s) {
- var o={};
- if ((o=this.ZOOM_MINMAX.exec(s))) { return [o[1],o[2]]; }
- else if ((o=this.ZOOM_MIN.exec(s) )) { return [o[1], maxscale]; }
- else if ((o=this.ZOOM_MAX.exec(s) )) { return [minscale, o[1]]; }
- else if ((o=this.ZOOM_SINGLE.exec(s))) { return [o[1],o[1]]; }
- return null;
- },
+ parseZoom:function(s) {
+ var o={};
+ if ((o=this.ZOOM_MINMAX.exec(s))) { return [o[1],o[2]]; }
+ else if ((o=this.ZOOM_MIN.exec(s) )) { return [o[1], maxscale]; }
+ else if ((o=this.ZOOM_MAX.exec(s) )) { return [minscale, o[1]]; }
+ else if ((o=this.ZOOM_SINGLE.exec(s))) { return [o[1],o[1]]; }
+ return null;
+ },
- parseCondition:function(s) {
- var o={};
- if ((o=this.CONDITION_TRUE.exec(s))) { return new iD.styleparser.Condition('true' ,o[1]); }
- else if ((o=this.CONDITION_FALSE.exec(s))) { return new iD.styleparser.Condition('false',o[1]); }
- else if ((o=this.CONDITION_SET.exec(s))) { return new iD.styleparser.Condition('set' ,o[1]); }
- else if ((o=this.CONDITION_UNSET.exec(s))) { return new iD.styleparser.Condition('unset',o[1]); }
- else if ((o=this.CONDITION_NE.exec(s))) { return new iD.styleparser.Condition('ne' ,o[1],o[2]); }
- else if ((o=this.CONDITION_GT.exec(s))) { return new iD.styleparser.Condition('>' ,o[1],o[2]); }
- else if ((o=this.CONDITION_GE.exec(s))) { return new iD.styleparser.Condition('>=' ,o[1],o[2]); }
- else if ((o=this.CONDITION_LT.exec(s))) { return new iD.styleparser.Condition('<' ,o[1],o[2]); }
- else if ((o=this.CONDITION_LE.exec(s))) { return new iD.styleparser.Condition('<=' ,o[1],o[2]); }
- else if ((o=this.CONDITION_REGEX.exec(s))) { return new iD.styleparser.Condition('regex',o[1],o[2]); }
- else if ((o=this.CONDITION_EQ.exec(s))) { return new iD.styleparser.Condition('eq' ,o[1],o[2]); }
- return null;
- },
+ parseCondition:function(s) {
+ var o={};
+ if ((o=this.CONDITION_TRUE.exec(s))) { return new iD.styleparser.Condition('true' ,o[1]); }
+ else if ((o=this.CONDITION_FALSE.exec(s))) { return new iD.styleparser.Condition('false',o[1]); }
+ else if ((o=this.CONDITION_SET.exec(s))) { return new iD.styleparser.Condition('set' ,o[1]); }
+ else if ((o=this.CONDITION_UNSET.exec(s))) { return new iD.styleparser.Condition('unset',o[1]); }
+ else if ((o=this.CONDITION_NE.exec(s))) { return new iD.styleparser.Condition('ne' ,o[1],o[2]); }
+ else if ((o=this.CONDITION_GT.exec(s))) { return new iD.styleparser.Condition('>' ,o[1],o[2]); }
+ else if ((o=this.CONDITION_GE.exec(s))) { return new iD.styleparser.Condition('>=' ,o[1],o[2]); }
+ else if ((o=this.CONDITION_LT.exec(s))) { return new iD.styleparser.Condition('<' ,o[1],o[2]); }
+ else if ((o=this.CONDITION_LE.exec(s))) { return new iD.styleparser.Condition('<=' ,o[1],o[2]); }
+ else if ((o=this.CONDITION_REGEX.exec(s))) { return new iD.styleparser.Condition('regex',o[1],o[2]); }
+ else if ((o=this.CONDITION_EQ.exec(s))) { return new iD.styleparser.Condition('eq' ,o[1],o[2]); }
+ return null;
+ },
- parseCSSColor:function(colorStr) {
- colorStr = colorStr.toLowerCase();
- if (this.CSSCOLORS[colorStr]) {
- return this.CSSCOLORS[colorStr];
- } else {
- var match = this.HEX.exec(colorStr);
- if ( match ) {
+ parseCSSColor:function(colorStr) {
+ colorStr = colorStr.toLowerCase();
+ if (this.CSSCOLORS[colorStr]) {
+ return this.CSSCOLORS[colorStr];
+ } else {
+ var match = this.HEX.exec(colorStr);
+ if ( match ) {
if ( match[1].length == 3) {
// repeat digits. #abc => 0xaabbcc
return Number("0x"+match[1].charAt(0)+match[1].charAt(0)+
match[1].charAt(1)+match[1].charAt(1)+
match[1].charAt(2)+match[1].charAt(2));
} else if ( match[1].length == 6) {
- return Number("0x"+match[1]);
- } else {
- return Number("0x000000"); //as good as any
- }
- }
- }
- return 0;
- },
+ return Number("0x"+match[1]);
+ } else {
+ return Number("0x000000"); //as good as any
+ }
+ }
+ }
+ return 0;
+ },
- // Regular expression tests and other constants
+ // Regular expression tests and other constants
- WHITESPACE :/^\s+/,
- COMMENT :/^\/\*.+?\*\/\s*/,
- CLASS :/^([\.:]\w+)\s*/,
- NOT_CLASS :/^!([\.:]\w+)\s*/,
- ZOOM :/^\|\s*z([\d\-]+)\s*/i,
- GROUP :/^,\s*/i,
- CONDITION :/^\[(.+?)\]\s*/,
- OBJECT :/^(\w+)\s*/,
- DECLARATION :/^\{(.+?)\}\s*/,
- SUBPART :/^::(\w+)\s*/,
- UNKNOWN :/^(\S+)\s*/,
+ WHITESPACE :/^\s+/,
+ COMMENT :/^\/\*.+?\*\/\s*/,
+CLASS :/^([\.:]\w+)\s*/,
+NOT_CLASS :/^!([\.:]\w+)\s*/,
+ZOOM :/^\|\s*z([\d\-]+)\s*/i,
+GROUP :/^,\s*/i,
+CONDITION :/^\[(.+?)\]\s*/,
+OBJECT :/^(\w+)\s*/,
+DECLARATION :/^\{(.+?)\}\s*/,
+SUBPART :/^::(\w+)\s*/,
+UNKNOWN :/^(\S+)\s*/,
- ZOOM_MINMAX :/^(\d+)\-(\d+)$/,
- ZOOM_MIN :/^(\d+)\-$/,
- ZOOM_MAX :/^\-(\d+)$/,
- ZOOM_SINGLE :/^(\d+)$/,
+ZOOM_MINMAX :/^(\d+)\-(\d+)$/,
+ZOOM_MIN :/^(\d+)\-$/,
+ZOOM_MAX :/^\-(\d+)$/,
+ZOOM_SINGLE :/^(\d+)$/,
- CONDITION_TRUE :/^\s*([:\w]+)\s*=\s*yes\s*$/i,
- CONDITION_FALSE :/^\s*([:\w]+)\s*=\s*no\s*$/i,
- CONDITION_SET :/^\s*([:\w]+)\s*$/,
- CONDITION_UNSET :/^\s*!([:\w]+)\s*$/,
- CONDITION_EQ :/^\s*([:\w]+)\s*=\s*(.+)\s*$/,
- CONDITION_NE :/^\s*([:\w]+)\s*!=\s*(.+)\s*$/,
- CONDITION_GT :/^\s*([:\w]+)\s*>\s*(.+)\s*$/,
- CONDITION_GE :/^\s*([:\w]+)\s*>=\s*(.+)\s*$/,
- CONDITION_LT :/^\s*([:\w]+)\s*<\s*(.+)\s*$/,
- CONDITION_LE :/^\s*([:\w]+)\s*<=\s*(.+)\s*$/,
- CONDITION_REGEX :/^\s*([:\w]+)\s*=~\/\s*(.+)\/\s*$/,
+CONDITION_TRUE :/^\s*([:\w]+)\s*=\s*yes\s*$/i,
+CONDITION_FALSE :/^\s*([:\w]+)\s*=\s*no\s*$/i,
+CONDITION_SET :/^\s*([:\w]+)\s*$/,
+CONDITION_UNSET :/^\s*!([:\w]+)\s*$/,
+CONDITION_EQ :/^\s*([:\w]+)\s*=\s*(.+)\s*$/,
+CONDITION_NE :/^\s*([:\w]+)\s*!=\s*(.+)\s*$/,
+CONDITION_GT :/^\s*([:\w]+)\s*>\s*(.+)\s*$/,
+CONDITION_GE :/^\s*([:\w]+)\s*>=\s*(.+)\s*$/,
+CONDITION_LT :/^\s*([:\w]+)\s*<\s*(.+)\s*$/,
+CONDITION_LE :/^\s*([:\w]+)\s*<=\s*(.+)\s*$/,
+CONDITION_REGEX :/^\s*([:\w]+)\s*=~\/\s*(.+)\/\s*$/,
- ASSIGNMENT_EVAL :/^\s*(\S+)\s*\:\s*eval\s*\(\s*'(.+?)'\s*\)\s*$/i,
- ASSIGNMENT :/^\s*(\S+)\s*\:\s*(.+?)\s*$/,
- SET_TAG_EVAL :/^\s*set\s+(\S+)\s*=\s*eval\s*\(\s*'(.+?)'\s*\)\s*$/i,
- SET_TAG :/^\s*set\s+(\S+)\s*=\s*(.+?)\s*$/i,
- SET_TAG_TRUE :/^\s*set\s+(\S+)\s*$/i,
- EXIT :/^\s*exit\s*$/i,
+ASSIGNMENT_EVAL :/^\s*(\S+)\s*\:\s*eval\s*\(\s*'(.+?)'\s*\)\s*$/i,
+ASSIGNMENT :/^\s*(\S+)\s*\:\s*(.+?)\s*$/,
+SET_TAG_EVAL :/^\s*set\s+(\S+)\s*=\s*eval\s*\(\s*'(.+?)'\s*\)\s*$/i,
+SET_TAG :/^\s*set\s+(\S+)\s*=\s*(.+?)\s*$/i,
+SET_TAG_TRUE :/^\s*set\s+(\S+)\s*$/i,
+EXIT :/^\s*exit\s*$/i,
- oZOOM: 2,
- oGROUP: 3,
- oCONDITION: 4,
- oOBJECT: 5,
- oDECLARATION: 6,
- oSUBPART: 7,
+oZOOM: 2,
+oGROUP: 3,
+oCONDITION: 4,
+oOBJECT: 5,
+oDECLARATION: 6,
+oSUBPART: 7,
- DASH: /\-/g,
- COLOR: /color$/,
- BOLD: /^bold$/i,
- ITALIC: /^italic|oblique$/i,
- UNDERLINE: /^underline$/i,
- CAPS: /^uppercase$/i,
- CENTER: /^center$/i,
- FALSE: /^(no|false|0)$/i,
+DASH: /\-/g,
+COLOR: /color$/,
+BOLD: /^bold$/i,
+ITALIC: /^italic|oblique$/i,
+UNDERLINE: /^underline$/i,
+CAPS: /^uppercase$/i,
+CENTER: /^center$/i,
+FALSE: /^(no|false|0)$/i,
- HEX: /^#([0-9a-f]+)$/i,
+HEX: /^#([0-9a-f]+)$/i,
- CSSCOLORS: {
- aliceblue:0xf0f8ff,
- antiquewhite:0xfaebd7,
- aqua:0x00ffff,
- aquamarine:0x7fffd4,
- azure:0xf0ffff,
- beige:0xf5f5dc,
- bisque:0xffe4c4,
- black:0x000000,
- blanchedalmond:0xffebcd,
- blue:0x0000ff,
- blueviolet:0x8a2be2,
- brown:0xa52a2a,
- burlywood:0xdeb887,
- cadetblue:0x5f9ea0,
- chartreuse:0x7fff00,
- chocolate:0xd2691e,
- coral:0xff7f50,
- cornflowerblue:0x6495ed,
- cornsilk:0xfff8dc,
- crimson:0xdc143c,
- cyan:0x00ffff,
- darkblue:0x00008b,
- darkcyan:0x008b8b,
- darkgoldenrod:0xb8860b,
- darkgray:0xa9a9a9,
- darkgreen:0x006400,
- darkkhaki:0xbdb76b,
- darkmagenta:0x8b008b,
- darkolivegreen:0x556b2f,
- darkorange:0xff8c00,
- darkorchid:0x9932cc,
- darkred:0x8b0000,
- darksalmon:0xe9967a,
- darkseagreen:0x8fbc8f,
- darkslateblue:0x483d8b,
- darkslategray:0x2f4f4f,
- darkturquoise:0x00ced1,
- darkviolet:0x9400d3,
- deeppink:0xff1493,
- deepskyblue:0x00bfff,
- dimgray:0x696969,
- dodgerblue:0x1e90ff,
- firebrick:0xb22222,
- floralwhite:0xfffaf0,
- forestgreen:0x228b22,
- fuchsia:0xff00ff,
- gainsboro:0xdcdcdc,
- ghostwhite:0xf8f8ff,
- gold:0xffd700,
- goldenrod:0xdaa520,
- gray:0x808080,
- green:0x008000,
- greenyellow:0xadff2f,
- honeydew:0xf0fff0,
- hotpink:0xff69b4,
- indianred:0xcd5c5c,
- indigo:0x4b0082,
- ivory:0xfffff0,
- khaki:0xf0e68c,
- lavender:0xe6e6fa,
- lavenderblush:0xfff0f5,
- lawngreen:0x7cfc00,
- lemonchiffon:0xfffacd,
- lightblue:0xadd8e6,
- lightcoral:0xf08080,
- lightcyan:0xe0ffff,
- lightgoldenrodyellow:0xfafad2,
- lightgrey:0xd3d3d3,
- lightgreen:0x90ee90,
- lightpink:0xffb6c1,
- lightsalmon:0xffa07a,
- lightseagreen:0x20b2aa,
- lightskyblue:0x87cefa,
- lightslategray:0x778899,
- lightsteelblue:0xb0c4de,
- lightyellow:0xffffe0,
- lime:0x00ff00,
- limegreen:0x32cd32,
- linen:0xfaf0e6,
- magenta:0xff00ff,
- maroon:0x800000,
- mediumaquamarine:0x66cdaa,
- mediumblue:0x0000cd,
- mediumorchid:0xba55d3,
- mediumpurple:0x9370d8,
- mediumseagreen:0x3cb371,
- mediumslateblue:0x7b68ee,
- mediumspringgreen:0x00fa9a,
- mediumturquoise:0x48d1cc,
- mediumvioletred:0xc71585,
- midnightblue:0x191970,
- mintcream:0xf5fffa,
- mistyrose:0xffe4e1,
- moccasin:0xffe4b5,
- navajowhite:0xffdead,
- navy:0x000080,
- oldlace:0xfdf5e6,
- olive:0x808000,
- olivedrab:0x6b8e23,
- orange:0xffa500,
- orangered:0xff4500,
- orchid:0xda70d6,
- palegoldenrod:0xeee8aa,
- palegreen:0x98fb98,
- paleturquoise:0xafeeee,
- palevioletred:0xd87093,
- papayawhip:0xffefd5,
- peachpuff:0xffdab9,
- peru:0xcd853f,
- pink:0xffc0cb,
- plum:0xdda0dd,
- powderblue:0xb0e0e6,
- purple:0x800080,
- red:0xff0000,
- rosybrown:0xbc8f8f,
- royalblue:0x4169e1,
- saddlebrown:0x8b4513,
- salmon:0xfa8072,
- sandybrown:0xf4a460,
- seagreen:0x2e8b57,
- seashell:0xfff5ee,
- sienna:0xa0522d,
- silver:0xc0c0c0,
- skyblue:0x87ceeb,
- slateblue:0x6a5acd,
- slategray:0x708090,
- snow:0xfffafa,
- springgreen:0x00ff7f,
- steelblue:0x4682b4,
- tan:0xd2b48c,
- teal:0x008080,
- thistle:0xd8bfd8,
- tomato:0xff6347,
- turquoise:0x40e0d0,
- violet:0xee82ee,
- wheat:0xf5deb3,
- white:0xffffff,
- whitesmoke:0xf5f5f5,
- yellow:0xffff00,
- yellowgreen:0x9acd32 },
+CSSCOLORS: {
+ aliceblue:0xf0f8ff,
+ antiquewhite:0xfaebd7,
+ aqua:0x00ffff,
+ aquamarine:0x7fffd4,
+ azure:0xf0ffff,
+ beige:0xf5f5dc,
+ bisque:0xffe4c4,
+ black:0x000000,
+ blanchedalmond:0xffebcd,
+ blue:0x0000ff,
+ blueviolet:0x8a2be2,
+ brown:0xa52a2a,
+ burlywood:0xdeb887,
+ cadetblue:0x5f9ea0,
+ chartreuse:0x7fff00,
+ chocolate:0xd2691e,
+ coral:0xff7f50,
+ cornflowerblue:0x6495ed,
+ cornsilk:0xfff8dc,
+ crimson:0xdc143c,
+ cyan:0x00ffff,
+ darkblue:0x00008b,
+ darkcyan:0x008b8b,
+ darkgoldenrod:0xb8860b,
+ darkgray:0xa9a9a9,
+ darkgreen:0x006400,
+ darkkhaki:0xbdb76b,
+ darkmagenta:0x8b008b,
+ darkolivegreen:0x556b2f,
+ darkorange:0xff8c00,
+ darkorchid:0x9932cc,
+ darkred:0x8b0000,
+ darksalmon:0xe9967a,
+ darkseagreen:0x8fbc8f,
+ darkslateblue:0x483d8b,
+ darkslategray:0x2f4f4f,
+ darkturquoise:0x00ced1,
+ darkviolet:0x9400d3,
+ deeppink:0xff1493,
+ deepskyblue:0x00bfff,
+ dimgray:0x696969,
+ dodgerblue:0x1e90ff,
+ firebrick:0xb22222,
+ floralwhite:0xfffaf0,
+ forestgreen:0x228b22,
+ fuchsia:0xff00ff,
+ gainsboro:0xdcdcdc,
+ ghostwhite:0xf8f8ff,
+ gold:0xffd700,
+ goldenrod:0xdaa520,
+ gray:0x808080,
+ green:0x008000,
+ greenyellow:0xadff2f,
+ honeydew:0xf0fff0,
+ hotpink:0xff69b4,
+ indianred:0xcd5c5c,
+ indigo:0x4b0082,
+ ivory:0xfffff0,
+ khaki:0xf0e68c,
+ lavender:0xe6e6fa,
+ lavenderblush:0xfff0f5,
+ lawngreen:0x7cfc00,
+ lemonchiffon:0xfffacd,
+ lightblue:0xadd8e6,
+ lightcoral:0xf08080,
+ lightcyan:0xe0ffff,
+ lightgoldenrodyellow:0xfafad2,
+ lightgrey:0xd3d3d3,
+ lightgreen:0x90ee90,
+ lightpink:0xffb6c1,
+ lightsalmon:0xffa07a,
+ lightseagreen:0x20b2aa,
+ lightskyblue:0x87cefa,
+ lightslategray:0x778899,
+ lightsteelblue:0xb0c4de,
+ lightyellow:0xffffe0,
+ lime:0x00ff00,
+ limegreen:0x32cd32,
+ linen:0xfaf0e6,
+ magenta:0xff00ff,
+ maroon:0x800000,
+ mediumaquamarine:0x66cdaa,
+ mediumblue:0x0000cd,
+ mediumorchid:0xba55d3,
+ mediumpurple:0x9370d8,
+ mediumseagreen:0x3cb371,
+ mediumslateblue:0x7b68ee,
+ mediumspringgreen:0x00fa9a,
+ mediumturquoise:0x48d1cc,
+ mediumvioletred:0xc71585,
+ midnightblue:0x191970,
+ mintcream:0xf5fffa,
+ mistyrose:0xffe4e1,
+ moccasin:0xffe4b5,
+ navajowhite:0xffdead,
+ navy:0x000080,
+ oldlace:0xfdf5e6,
+ olive:0x808000,
+ olivedrab:0x6b8e23,
+ orange:0xffa500,
+ orangered:0xff4500,
+ orchid:0xda70d6,
+ palegoldenrod:0xeee8aa,
+ palegreen:0x98fb98,
+ paleturquoise:0xafeeee,
+ palevioletred:0xd87093,
+ papayawhip:0xffefd5,
+ peachpuff:0xffdab9,
+ peru:0xcd853f,
+ pink:0xffc0cb,
+ plum:0xdda0dd,
+ powderblue:0xb0e0e6,
+ purple:0x800080,
+ red:0xff0000,
+ rosybrown:0xbc8f8f,
+ royalblue:0x4169e1,
+ saddlebrown:0x8b4513,
+ salmon:0xfa8072,
+ sandybrown:0xf4a460,
+ seagreen:0x2e8b57,
+ seashell:0xfff5ee,
+ sienna:0xa0522d,
+ silver:0xc0c0c0,
+ skyblue:0x87ceeb,
+ slateblue:0x6a5acd,
+ slategray:0x708090,
+ snow:0xfffafa,
+ springgreen:0x00ff7f,
+ steelblue:0x4682b4,
+ tan:0xd2b48c,
+ teal:0x008080,
+ thistle:0xd8bfd8,
+ tomato:0xff6347,
+ turquoise:0x40e0d0,
+ violet:0xee82ee,
+ wheat:0xf5deb3,
+ white:0xffffff,
+ whitesmoke:0xf5f5f5,
+ yellow:0xffff00,
+ yellowgreen:0x9acd32 },
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
+};
diff --git a/js/iD/styleparser/Style.js b/js/iD/styleparser/Style.js
index 4bde63d76..193b34b76 100755
--- a/js/iD/styleparser/Style.js
+++ b/js/iD/styleparser/Style.js
@@ -1,12 +1,6 @@
-// iD/styleparser/Style.js
+iD.styleparser.Style = function() {};
-define(['dojo/_base/declare','dojo/_base/array'], function(declare,array){
-
-// ----------------------------------------------------------------------
-// Style base class
-// fillStyler not done for text yet
-
-declare("iD.styleparser.Style", null, {
+iD.styleparser.Style.prototype = {
merged: false,
edited: false,
sublayer: 5,
@@ -54,7 +48,8 @@ declare("iD.styleparser.Style", null, {
runEvals: function(tags) {
for (var k in this.evals) {
- this.setPropertyFromString(k,eval("with (tags) {"+this.evals[k]+"}"),false);
+ // TODO: kill
+ this.setPropertyFromString(k, eval("with (tags) {"+this.evals[k]+"}"),false);
}
},
@@ -72,13 +67,14 @@ declare("iD.styleparser.Style", null, {
}
return str;
}
-});
+};
// ----------------------------------------------------------------------
// InstructionStyle class
-declare("iD.styleparser.InstructionStyle", [iD.styleparser.Style], {
+iD.styleparser.InstructionStyle = function() {};
+iD.styleparser.InstructionStyle.prototype = {
set_tags: null,
breaker: false,
styleType: 'InstructionStyle',
@@ -87,12 +83,13 @@ declare("iD.styleparser.InstructionStyle", [iD.styleparser.Style], {
if (!this.set_tags) this.set_tags={};
this.set_tags[k]=v;
}
-});
+};
// ----------------------------------------------------------------------
// PointStyle class
-declare("iD.styleparser.PointStyle", [iD.styleparser.Style], {
+iD.styleparser.PointStyle = function() {};
+iD.styleparser.PointStyle.prototype = {
properties: ['icon_image','icon_width','icon_height','rotation'],
icon_image: null,
icon_width: 0,
@@ -105,12 +102,14 @@ declare("iD.styleparser.PointStyle", [iD.styleparser.Style], {
maxwidth:function() {
return this.evals.icon_width ? 0 : this.icon_width;
}
-});
+};
// ----------------------------------------------------------------------
// ShapeStyle class
-declare("iD.styleparser.ShapeStyle", [iD.styleparser.Style], {
+iD.styleparser.ShapeStyle = function() {};
+
+iD.styleparser.ShapeStyle.prototype = {
properties: ['width','color','opacity','dashes','linecap','linejoin','line_style',
'fill_image','fill_color','fill_opacity','casing_width','casing_color','casing_opacity','casing_dashes','layer'],
@@ -168,13 +167,13 @@ declare("iD.styleparser.ShapeStyle", [iD.styleparser.Style], {
join: join
};
}
-});
+};
// ----------------------------------------------------------------------
// TextStyle class
-declare("iD.styleparser.TextStyle", [iD.styleparser.Style], {
-
+iD.styleparser.TextStyle = function() {};
+iD.styleparser.TextStyle.prototype = {
properties: ['font_family','font_bold','font_italic','font_caps','font_underline','font_size',
'text_color','text_offset','max_width',
'text','text_halo_color','text_halo_radius','text_center',
@@ -219,13 +218,15 @@ declare("iD.styleparser.TextStyle", [iD.styleparser.Style], {
return this.dojoColor(0,1);
}
// getTextFormat, getHaloFilter, writeNameLabel
-});
+};
// ----------------------------------------------------------------------
// ShieldStyle class
-declare("iD.styleparser.ShieldStyle", [iD.styleparser.Style], {
- properties: ['shield_image','shield_width','shield_height'],
+iD.styleparser.ShieldStyle = function() {};
+
+iD.styleparser.ShieldStyle.prototype = {
+ properties: ['shield_image','shield_width','shield_height'],
shield_image: null,
shield_width: NaN,
shield_height: NaN,
@@ -233,8 +234,7 @@ declare("iD.styleparser.ShieldStyle", [iD.styleparser.Style], {
drawn:function() {
return (shield_image !== null);
}
-});
+};
// ----------------------------------------------------------------------
// End of module
-});
diff --git a/js/iD/styleparser/StyleChooser.js b/js/iD/styleparser/StyleChooser.js
index 8b856f2b8..f2143d925 100755
--- a/js/iD/styleparser/StyleChooser.js
+++ b/js/iD/styleparser/StyleChooser.js
@@ -1,14 +1,15 @@
// iD/styleparser/StyleChooser.js
-define(['dojo/_base/declare','dojo/_base/lang','iD/styleparser/RuleChain'], function(declare,lang){
-
-declare("iD.styleparser.StyleChooser", null, {
+iD.styleparser.StyleChooser = function() {
+ this.ruleChains = [new iD.styleparser.RuleChain()];
+ this.styles = [];
+};
+iD.styleparser.StyleChooser.prototype = {
// UpdateStyles doesn't support image-widths yet
// or setting maxwidth/_width
-
- ruleChains:[], // array of RuleChains (each one an array of Rules)
- styles:[], // array of ShapeStyle/ShieldStyle/TextStyle/PointStyle
+ ruleChains: [], // array of RuleChains (each one an array of Rules)
+ styles: [], // array of ShapeStyle/ShieldStyle/TextStyle/PointStyle
zoomSpecific:false, // are any of the rules zoom-specific?
rcpos:0,
@@ -17,8 +18,6 @@ declare("iD.styleparser.StyleChooser", null, {
constructor:function() {
// summary: A combination of the selectors (ruleChains) and declaration (styles).
// For example, way[highway=footway] node[barrier=gate] { icon: gate.png; } is one StyleChooser.
- this.ruleChains=[new iD.styleparser.RuleChain()];
- this.styles=[];
},
currentChain:function() {
@@ -80,8 +79,4 @@ declare("iD.styleparser.StyleChooser", null, {
}
}
}
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
+};
diff --git a/js/iD/styleparser/StyleList.js b/js/iD/styleparser/StyleList.js
index e9bc441b7..801162c16 100755
--- a/js/iD/styleparser/StyleList.js
+++ b/js/iD/styleparser/StyleList.js
@@ -1,12 +1,7 @@
-// iD/styleparser/StyleList.js
-
-define(['dojo/_base/declare'], function(declare){
-
// ----------------------------------------------------------------------
// StyleList class
-
-
-declare("iD.styleparser.StyleList", null, {
+iD.styleparser.StyleList = function() {};
+iD.styleparser.StyleList.prototype = {
shapeStyles: {},
textStyles: {},
@@ -16,17 +11,6 @@ declare("iD.styleparser.StyleList", null, {
subparts: [], // List of subparts used in this StyleList
validAt: -1, // Zoom level this is valid at (or -1 at all levels - saves recomputing)
- constructor:function() {
- // summary: A StyleList object is the full list of all styles applied to
- // a drawn entity (i.e. node/way). Each array element applies to that
- // sublayer (z-index). If there is no element, nothing is drawn on that sublayer.
- // StyleLists are created by StyleChooser.getStyles.
- this.shapeStyles={};
- this.textStyles={};
- this.pointStyles={};
- this.shieldStyles={};
- this.subparts=[];
- },
hasStyles:function() {
// summary: Does this StyleList contain any styles?
@@ -74,8 +58,4 @@ declare("iD.styleparser.StyleList", null, {
hasTextStyles:function() { for (var a in textStyles ) { return true; } return false; },
hasPointStyles:function() { for (var a in pointStyles ) { return true; } return false; },
hasShieldStyles:function() { for (var a in shieldStyles) { return true; } return false; }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
+};
diff --git a/js/iD/styleparser/styleparser.js b/js/iD/styleparser/styleparser.js
new file mode 100644
index 000000000..51c9fce18
--- /dev/null
+++ b/js/iD/styleparser/styleparser.js
@@ -0,0 +1 @@
+iD.styleparser = {};
diff --git a/js/lib/d3.v2.min.js b/js/lib/d3.v2.min.js
new file mode 100644
index 000000000..0b4ea58fd
--- /dev/null
+++ b/js/lib/d3.v2.min.js
@@ -0,0 +1,4 @@
+(function(){function e(e,t){try{for(var n in t)Object.defineProperty(e.prototype,n,{value:t[n],enumerable:!1})}catch(r){e.prototype=t}}function t(e){var t=-1,n=e.length,r=[];while(++t=0?e.substring(t):(t=e.length,""),r=[];while(t>0)r.push(e.substring(t-=3,t+3));return r.reverse().join(",")+n}function b(e,t){var n=Math.pow(10,Math.abs(8-t)*3);return{scale:t>8?function(e){return e/n}:function(e){return e*n},symbol:e}}function w(e){return function(t){return t<=0?0:t>=1?1:e(t)}}function E(e){return function(t){return 1-e(1-t)}}function S(e){return function(t){return.5*(t<.5?e(2*t):2-e(2-2*t))}}function x(e){return e}function T(e){return function(t){return Math.pow(t,e)}}function N(e){return 1-Math.cos(e*Math.PI/2)}function C(e){return Math.pow(2,10*(e-1))}function k(e){return 1-Math.sqrt(1-e*e)}function L(e,t){var n;return arguments.length<2&&(t=.45),arguments.length<1?(e=1,n=t/4):n=t/(2*Math.PI)*Math.asin(1/e),function(r){return 1+e*Math.pow(2,10*-r)*Math.sin((r-n)*2*Math.PI/t)}}function A(e){return e||(e=1.70158),function(t){return t*t*((e+1)*t-e)}}function O(e){return e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375}function M(){d3.event.stopPropagation(),d3.event.preventDefault()}function _(){var e=d3.event,t;while(t=e.sourceEvent)e=t;return e}function D(e){var t=new d,n=0,r=arguments.length;while(++n360?e-=360:e<0&&(e+=360),e<60?s+(o-s)*e/60:e<180?o:e<240?s+(o-s)*(240-e)/60:s}function i(e){return Math.round(r(e)*255)}var s,o;return e%=360,e<0&&(e+=360),t=t<0?0:t>1?1:t,n=n<0?0:n>1?1:n,o=n<=.5?n*(1+t):n+t-n*t,s=2*n-o,U(i(e+120),i(e),i(e-120))}function Z(e,t,n){return new et(e,t,n)}function et(e,t,n){this.h=e,this.c=t,this.l=n}function tt(e,t,n){return nt(n,Math.cos(e*=Math.PI/180)*t,Math.sin(e)*t)}function nt(e,t,n){return new rt(e,t,n)}function rt(e,t,n){this.l=e,this.a=t,this.b=n}function it(e,t,n){var r=(e+16)/116,i=r+t/500,s=r-n/200;return i=ot(i)*ys,r=ot(r)*bs,s=ot(s)*ws,U(at(3.2404542*i-1.5371385*r-.4985314*s),at(-0.969266*i+1.8760108*r+.041556*s),at(.0556434*i-.2040259*r+1.0572252*s))}function st(e,t,n){return Z(Math.atan2(n,t)/Math.PI*180,Math.sqrt(t*t+n*n),e)}function ot(e){return e>.206893034?e*e*e:(e-4/29)/7.787037}function ut(e){return e>.008856?Math.pow(e,1/3):7.787037*e+4/29}function at(e){return Math.round(255*(e<=.00304?12.92*e:1.055*Math.pow(e,1/2.4)-.055))}function ft(e){return Qi(e,ks),e}function lt(e){return function(){return Ss(e,this)}}function ct(e){return function(){return xs(e,this)}}function ht(e,t){function n(){this.removeAttribute(e)}function r(){this.removeAttributeNS(e.space,e.local)}function i(){this.setAttribute(e,t)}function s(){this.setAttributeNS(e.space,e.local,t)}function o(){var n=t.apply(this,arguments);n==null?this.removeAttribute(e):this.setAttribute(e,n)}function u(){var n=t.apply(this,arguments);n==null?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}return e=d3.ns.qualify(e),t==null?e.local?r:n:typeof t=="function"?e.local?u:o:e.local?s:i}function pt(e){return new RegExp("(?:^|\\s+)"+d3.requote(e)+"(?:\\s+|$)","g")}function dt(e,t){function n(){var n=-1;while(++n0&&(e=e.substring(0,o)),t?i:r}function St(e,t){for(var n=0,r=e.length;nt?c():(v.active=t,i.forEach(function(t,n){(n=n.call(e,m,u))&&h.push(n)}),s.start.call(e,m,u),l(r)||d3.timer(l,0,n),1)}function l(n){if(v.active!==t)return c();var r=(n-p)/d,i=o(r),a=h.length;while(a>0)h[--a].call(e,i);if(r>=1)return c(),_s=t,s.end.call(e,m,u),_s=0,1}function c(){return--v.count||delete e.__transition__,1}var h=[],p=e.delay,d=e.duration,v=(e=e.node).__transition__||(e.__transition__={active:0,count:0}),m=e.__data__;++v.count,p<=r?f(r):d3.timer(f,p,n)})},0,n),e}function Nt(e){var t=_s,n=Fs,r=Bs,i=js;return _s=this.id,Fs=this.ease(),St(this,function(t,n,r){Bs=t.delay,js=t.duration,e.call(t=t.node,t.__data__,n,r)}),_s=t,Fs=n,Bs=r,js=i,this}function Ct(e,t,n){return n!=""&&Is}function kt(e,t){return d3.tween(e,F(t))}function Lt(){var e,t=Date.now(),n=Us;while(n)e=t-n.then,e>=n.delay&&(n.flush=n.callback(e)),n=n.next;var r=At()-t;r>24?(isFinite(r)&&(clearTimeout(Ws),Ws=setTimeout(Lt,r)),zs=0):(zs=1,Xs(Lt))}function At(){var e=null,t=Us,n=Infinity;while(t)t.flush?(delete Rs[t.callback.id],t=e?e.next=t.next:Us=t.next):(n=Math.min(n,t.then+t.delay),t=(e=t).next);return n}function Ot(e,t){var n=e.ownerSVGElement||e;if(n.createSVGPoint){var r=n.createSVGPoint();if(Vs<0&&(window.scrollX||window.scrollY)){n=d3.select(document.body).append("svg").style("position","absolute").style("top",0).style("left",0);var i=n[0][0].getScreenCTM();Vs=!i.f&&!i.e,n.remove()}return Vs?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(e.getScreenCTM().inverse()),[r.x,r.y]}var s=e.getBoundingClientRect();return[t.clientX-s.left-e.clientLeft,t.clientY-s.top-e.clientTop]}function Mt(){}function _t(e){var t=e[0],n=e[e.length-1];return t2?zt:Ut,a=r?q:I;return o=i(e,t,a,n),u=i(t,e,a,d3.interpolate),s}function s(e){return o(e)}var o,u;return s.invert=function(e){return u(e)},s.domain=function(t){return arguments.length?(e=t.map(Number),i()):e},s.range=function(e){return arguments.length?(t=e,i()):t},s.rangeRound=function(e){return s.range(e).interpolate(d3.interpolateRound)},s.clamp=function(e){return arguments.length?(r=e,i()):r},s.interpolate=function(e){return arguments.length?(n=e,i()):n},s.ticks=function(t){return qt(e,t)},s.tickFormat=function(t){return Rt(e,t)},s.nice=function(){return Pt(e,Ft),i()},s.copy=function(){return Bt(e,t,n,r)},i()}function jt(e,t){return d3.rebind(e,t,"range","rangeRound","interpolate","clamp")}function Ft(e){return e=Math.pow(10,Math.round(Math.log(e)/Math.LN10)-1),e&&{floor:function(t){return Math.floor(t/e)*e},ceil:function(t){return Math.ceil(t/e)*e}}}function It(e,t){var n=_t(e),r=n[1]-n[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),s=t/r*i;return s<=.15?i*=10:s<=.35?i*=5:s<=.75&&(i*=2),n[0]=Math.ceil(n[0]/i)*i,n[1]=Math.floor(n[1]/i)*i+i*.5,n[2]=i,n}function qt(e,t){return d3.range.apply(d3,It(e,t))}function Rt(e,t){return d3.format(",."+Math.max(0,-Math.floor(Math.log(It(e,t)[2])/Math.LN10+.01))+"f")}function Ut(e,t,n,r){var i=n(e[0],e[1]),s=r(t[0],t[1]);return function(e){return s(i(e))}}function zt(e,t,n,r){var i=[],s=[],o=0,u=Math.min(e.length,t.length)-1;e[u]0;f--)i.push(r(s)*f)}else{for(;sa;o--);i=i.slice(s,o)}return i},n.tickFormat=function(e,i){arguments.length<2&&(i=$s);if(arguments.length<1)return i;var s=Math.max(.1,e/n.ticks().length),o=t===Vt?(u=-1e-12,Math.floor):(u=1e-12,Math.ceil),u;return function(e){return e/r(o(t(e)+u))<=s?i(e):""}},n.copy=function(){return Wt(e.copy(),t)},jt(n,e)}function Xt(e){return Math.log(e<0?0:e)/Math.LN10}function Vt(e){return-Math.log(e>0?0:-e)/Math.LN10}function $t(e,t){function n(t){return e(r(t))}var r=Jt(t),i=Jt(1/t);return n.invert=function(t){return i(e.invert(t))},n.domain=function(t){return arguments.length?(e.domain(t.map(r)),n):e.domain().map(i)},n.ticks=function(e){return qt(n.domain(),e)},n.tickFormat=function(e){return Rt(n.domain(),e)},n.nice=function(){return n.domain(Pt(n.domain(),Ft))},n.exponent=function(e){if(!arguments.length)return t;var s=n.domain();return r=Jt(t=e),i=Jt(1/t),n.domain(s)},n.copy=function(){return $t(e.copy(),t)},jt(n,e)}function Jt(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function Kt(e,t){function n(t){return o[((s.get(t)||s.set(t,e.push(t)))-1)%o.length]}function i(t,n){return d3.range(e.length).map(function(e){return t+n*e})}var s,o,u;return n.domain=function(i){if(!arguments.length)return e;e=[],s=new r;var o=-1,u=i.length,a;while(++o1){u=t[1],s=e[a],a++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(s[0]-u[0])+","+(s[1]-u[1])+","+s[0]+","+s[1];for(var f=2;f9&&(s=n*3/Math.sqrt(s),o[u]=s*r,o[u+1]=s*i));u=-1;while(++u<=a)s=(e[Math.min(a,u+1)][0]-e[Math.max(0,u-1)][0])/(6*(1+o[u]*o[u])),t.push([s||0,o[u]*s||0]);return t}function Cn(e){return e.length<3?an(e):e[0]+vn(e,Nn(e))}function kn(e){var t,n=-1,r=e.length,i,s;while(++n1){var r=_t(e.domain()),i,s=-1,o=t.length,u=(t[1]-t[0])/++n,a,f;while(++s0;)(f=+t[s]-a*u)>=r[0]&&i.push(f);for(--s,a=0;++ar&&(n=t,r=i);return n}function sr(e){return e.reduce(or,0)}function or(e,t){return e+t[1]}function ur(e,t){return ar(e,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ar(e,t){var n=-1,r=+e[0],i=(e[1]-r)/t,s=[];while(++n<=t)s[n]=i*n+r;return s}function fr(e){return[d3.min(e),d3.max(e)]}function lr(e,t){return d3.rebind(e,t,"sort","children","value"),e.links=dr,e.nodes=function(t){return vo=!0,(e.nodes=e)(t)},e}function cr(e){return e.children}function hr(e){return e.value}function pr(e,t){return t.value-e.value}function dr(e){return d3.merge(e.map(function(e){return(e.children||[]).map(function(t){return{source:e,target:t}})}))}function vr(e,t){return e.value-t.value}function mr(e,t){var n=e._pack_next;e._pack_next=t,t._pack_prev=e,t._pack_next=n,n._pack_prev=t}function gr(e,t){e._pack_next=t,t._pack_prev=e}function yr(e,t){var n=t.x-e.x,r=t.y-e.y,i=e.r+t.r;return i*i-n*n-r*r>.001}function br(e){function t(e){r=Math.min(e.x-e.r,r),i=Math.max(e.x+e.r,i),s=Math.min(e.y-e.r,s),o=Math.max(e.y+e.r,o)}if(!(n=e.children)||!(p=n.length))return;var n,r=Infinity,i=-Infinity,s=Infinity,o=-Infinity,u,a,f,l,c,h,p;n.forEach(wr),u=n[0],u.x=-u.r,u.y=0,t(u);if(p>1){a=n[1],a.x=a.r,a.y=0,t(a);if(p>2){f=n[2],xr(u,a,f),t(f),mr(u,f),u._pack_prev=f,mr(f,a),a=u._pack_next;for(l=3;l0&&(e=r)}return e}function _r(e,t){return e.x-t.x}function Dr(e,t){return t.x-e.x}function Pr(e,t){return e.depth-t.depth}function Hr(e,t){function n(e,r){var i=e.children;if(i&&(a=i.length)){var s,o=null,u=-1,a;while(++u=0)s=r[i]._tree,s.prelim+=t,s.mod+=t,t+=s.shift+(n+=s.change)}function jr(e,t,n){e=e._tree,t=t._tree;var r=n/(t.number-e.number);e.change+=r,t.change-=r,t.shift+=n,t.prelim+=n,t.mod+=n}function Fr(e,t,n){return e._tree.ancestor.parent==t.parent?e._tree.ancestor:n}function Ir(e){return{x:e.x,y:e.y,dx:e.dx,dy:e.dy}}function qr(e,t){var n=e.x+t[3],r=e.y+t[0],i=e.dx-t[1]-t[3],s=e.dy-t[0]-t[2];return i<0&&(n+=i/2,i=0),s<0&&(r+=s/2,s=0),{x:n,y:r,dx:i,dy:s}}function Rr(e,t){function n(e,r){d3.text(e,t,function(e){r(e&&n.parse(e))})}function r(t){return t.map(i).join(e)}function i(e){return o.test(e)?'"'+e.replace(/\"/g,'""')+'"':e}var s=new RegExp("\r\n|["+e+"\r\n]","g"),o=new RegExp('["'+e+"\n]"),u=e.charCodeAt(0);return n.parse=function(e){var t;return n.parseRows(e,function(e,n){if(n){var r={},i=-1,s=t.length;while(++i=e.length)return i;if(l)return l=!1,r;var t=s.lastIndex;if(e.charCodeAt(t)===34){var n=t;while(n++0}function si(e,t,n){return(n[0]-t[0])*(e[1]-t[1])<(n[1]-t[1])*(e[0]-t[0])}function oi(e,t,n,r){var i=e[0],s=t[0],o=n[0],u=r[0],a=e[1],f=t[1],l=n[1],c=r[1],h=i-o,p=s-i,d=u-o,v=a-l,m=f-a,g=c-l,y=(d*v-g*h)/(g*p-d*m);return[i+y*p,a+y*m]}function ui(e,t){var n={list:e.map(function(e,t){return{index:t,x:e[0],y:e[1]}}).sort(function(e,t){return e.yt.y?1:e.xt.x?1:0}),bottomSite:null},r={list:[],leftEnd:null,rightEnd:null,init:function(){r.leftEnd=r.createHalfEdge(null,"l"),r.rightEnd=r.createHalfEdge(null,"l"),r.leftEnd.r=r.rightEnd,r.rightEnd.l=r.leftEnd,r.list.unshift(r.leftEnd,r.rightEnd)},createHalfEdge:function(e,t){return{edge:e,side:t,vertex:null,l:null,r:null}},insert:function(e,t){t.l=e,t.r=e.r,e.r.l=t,e.r=t},leftBound:function(e){var t=r.leftEnd;do t=t.r;while(t!=r.rightEnd&&i.rightOf(t,e));return t=t.l,t},del:function(e){e.l.r=e.r,e.r.l=e.l,e.edge=null},right:function(e){return e.r},left:function(e){return e.l},leftRegion:function(e){return e.edge==null?n.bottomSite:e.edge.region[e.side]},rightRegion:function(e){return e.edge==null?n.bottomSite:e.edge.region[wo[e.side]]}},i={bisect:function(e,t){var n={region:{l:e,r:t},ep:{l:null,r:null}},r=t.x-e.x,i=t.y-e.y,s=r>0?r:-r,o=i>0?i:-i;return n.c=e.x*r+e.y*i+(r*r+i*i)*.5,s>o?(n.a=1,n.b=i/r,n.c/=r):(n.b=1,n.a=r/i,n.c/=i),n},intersect:function(e,t){var n=e.edge,r=t.edge;if(!n||!r||n.region.r==r.region.r)return null;var i=n.a*r.b-n.b*r.a;if(Math.abs(i)<1e-10)return null;var s=(n.c*r.b-r.c*n.b)/i,o=(r.c*n.a-n.c*r.a)/i,u=n.region.r,a=r.region.r,f,l;u.y=l.region.r.x;return c&&f.side==="l"||!c&&f.side==="r"?null:{x:s,y:o}},rightOf:function(e,t){var n=e.edge,r=n.region.r,i=t.x>r.x;if(i&&e.side==="l")return 1;if(!i&&e.side==="r")return 0;if(n.a===1){var s=t.y-r.y,o=t.x-r.x,u=0,a=0;!i&&n.b<0||i&&n.b>=0?a=u=s>=n.b*o:(a=t.x+t.y*n.b>n.c,n.b<0&&(a=!a),a||(u=1));if(!u){var f=r.x-n.region.l.x;a=n.b*(o*o-s*s)h*h+p*p}return e.side==="l"?a:!a},endPoint:function(e,n,r){e.ep[n]=r;if(!e.ep[wo[n]])return;t(e)},distance:function(e,t){var n=e.x-t.x,r=e.y-t.y;return Math.sqrt(n*n+r*r)}},s={list:[],insert:function(e,t,n){e.vertex=t,e.ystar=t.y+n;for(var r=0,i=s.list,o=i.length;ru.ystar||e.ystar==u.ystar&&t.x>u.vertex.x)continue;break}i.splice(r,0,e)},del:function(e){for(var t=0,n=s.list,r=n.length;td.y&&(v=p,p=d,d=v,b="r"),y=i.bisect(p,d),h=r.createHalfEdge(y,b),r.insert(l,h),i.endPoint(y,wo[b],g),m=i.intersect(l,h),m&&(s.del(l),s.insert(l,m,i.distance(m,p))),m=i.intersect(h,c),m&&s.insert(h,m,i.distance(m,p))}}for(a=r.right(r.leftEnd);a!=r.rightEnd;a=r.right(a))t(a.edge)}function ai(){return{leaf:!0,nodes:[],point:null}}function fi(e,t,n,r,i,s){if(!e(t,n,r,i,s)){var o=(n+i)*.5,u=(r+s)*.5,a=t.nodes;a[0]&&fi(e,a[0],n,r,o,u),a[1]&&fi(e,a[1],o,r,i,u),a[2]&&fi(e,a[2],n,u,o,s),a[3]&&fi(e,a[3],o,u,i,s)}}function li(e){return{x:e[0],y:e[1]}}function ci(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function hi(e){return e.substring(0,3)}function pi(e,t,n,r){var i,s,o=0,u=t.length,a=n.length;while(o=a)return-1;i=t.charCodeAt(o++);if(i==37){s=Uo[t.charAt(o++)];if(!s||(r=s(e,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}function di(e){return new RegExp("^(?:"+e.map(d3.requote).join("|")+")","i")}function vi(e){var t=new r,n=-1,i=e.length;while(++n68?1900:2e3)}function Ci(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.m=r[0]-1,n+=r[0].length):-1}function ki(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.d=+r[0],n+=r[0].length):-1}function Li(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.H=+r[0],n+=r[0].length):-1}function Ai(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.M=+r[0],n+=r[0].length):-1}function Oi(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.S=+r[0],n+=r[0].length):-1}function Mi(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+3));return r?(e.L=+r[0],n+=r[0].length):-1}function _i(e,t,n){var r=Wo.get(t.substring(n,n+=2).toLowerCase());return r==null?-1:(e.p=r,n)}function Di(e){var t=e.getTimezoneOffset(),n=t>0?"-":"+",r=~~(Math.abs(t)/60),i=Math.abs(t)%60;return n+Mo(r)+Mo(i)}function Pi(e){return e.toISOString()}function Hi(e,t,n){function r(t){var n=e(t),r=s(n,1);return t-n1)while(ot?1:e>=t?0:NaN},d3.descending=function(e,t){return te?1:t>=e?0:NaN},d3.mean=function(e,t){var n=e.length,r,i=0,s=-1,o=0;if(arguments.length===1)while(++s1&&(e=e.map(t)),e=e.filter(f),e.length?d3.quantile(e.sort(d3.ascending),.5):undefined},d3.min=function(e,t){var n=-1,r=e.length,i,s;if(arguments.length===1){while(++ns&&(i=s)}else{while(++ns&&(i=s)}return i},d3.max=function(e,t){var n=-1,r=e.length,i,s;if(arguments.length===1){while(++ni&&(i=s)}else{while(++ni&&(i=s)}return i},d3.extent=function(e,t){var n=-1,r=e.length,i,s,o;if(arguments.length===1){while(++ns&&(i=s),os&&(i=s),o1);return e+t*n*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(e,t){var n=arguments.length;n<2&&(t=1),n<1&&(e=0);var r=d3.random.normal();return function(){return Math.exp(e+t*r())}},irwinHall:function(e){return function(){for(var t=0,n=0;n>>1;e.call(t,t[s],s)>>1;n0&&(i=s);return i},d3.last=function(e,t){var n=0,r=e.length,i=e[0],s;arguments.length===1&&(t=d3.ascending);while(++n=i.length)return u?u.call(n,t):o?t.sort(o):t;var a=-1,f=t.length,l=i[s++],c,h,p=new r,d,v={};while(++a=i.length)return e;var r=[],o=s[n++],u;for(u in e)r.push({key:u,values:t(e[u],n)});return o&&r.sort(function(e,t){return o(e.key,t.key)}),r}var n={},i=[],s=[],o,u;return n.map=function(t){return e(t,0)},n.entries=function(n){return t(e(n,0),0)},n.key=function(e){return i.push(e),n},n.sortKeys=function(e){return s[i.length-1]=e,n},n.sortValues=function(e){return o=e,n},n.rollup=function(e){return u=e,n},n},d3.keys=function(e){var t=[];for(var n in e)t.push(n);return t},d3.values=function(e){var t=[];for(var n in e)t.push(e[n]);return t},d3.entries=function(e){var t=[];for(var n in e)t.push({key:n,value:e[n]});return t},d3.permute=function(e,t){var n=[],r=-1,i=t.length;while(++rt)r.push(o/i);else while((o=e+n*++s)=200&&e<300||e===304?r:null)}},r.send(null)},d3.text=function(e,t,n){function r(e){n(e&&e.responseText)}arguments.length<3&&(n=t,t=null),d3.xhr(e,t,r)},d3.json=function(e,t){d3.text(e,"application/json",function(e){t(e?JSON.parse(e):null)})},d3.html=function(e,t){d3.text(e,"text/html",function(e){if(e!=null){var n=document.createRange();n.selectNode(document.body),e=n.createContextualFragment(e)}t(e)})},d3.xml=function(e,t,n){function r(e){n(e&&e.responseXML)}arguments.length<3&&(n=t,t=null),d3.xhr(e,t,r)};var ts={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};d3.ns={prefix:ts,qualify:function(e){var t=e.indexOf(":"),n=e;return t>=0&&(n=e.substring(0,t),e=e.substring(t+1)),ts.hasOwnProperty(n)?{space:ts[n],local:e}:e}},d3.dispatch=function(){var e=new d,t=-1,n=arguments.length;while(++t0&&(r=e.substring(n+1),e=e.substring(0,n)),arguments.length<2?this[e].on(r):this[e].on(r,t)},d3.format=function(e){var t=ns.exec(e),n=t[1]||" ",r=t[3]||"",i=t[5],s=+t[6],o=t[7],u=t[8],a=t[9],f=1,l="",c=!1;u&&(u=+u.substring(1)),i&&(n="0",o&&(s-=Math.floor((s-1)/4)));switch(a){case"n":o=!0,a="g";break;case"%":f=100,l="%",a="f";break;case"p":f=100,l="%",a="r";break;case"d":c=!0,u=0;break;case"s":f=-1,a="r"}return a=="r"&&!u&&(a="g"),a=rs.get(a)||g,function(e){if(c&&e%1)return"";var t=e<0&&(e=-e)?"-":r;if(f<0){var h=d3.formatPrefix(e,u);e=h.scale(e),l=h.symbol}else e*=f;e=a(e,u);if(i){var p=e.length+t.length;p=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,rs=d3.map({g:function(e,t){return e.toPrecision(t)},e:function(e,t){return e.toExponential(t)},f:function(e,t){return e.toFixed(t)},r:function(e,t){return d3.round(e,t=m(e,t)).toFixed(Math.max(0,Math.min(20,t)))}}),is=["y","z","a","f","p","n","μ","m","","k","M","G","T","P","E","Z","Y"].map(b);d3.formatPrefix=function(e,t){var n=0;return e&&(e<0&&(e*=-1),t&&(e=d3.round(e,m(e,t))),n=1+Math.floor(1e-12+Math.log(e)/Math.LN10),n=Math.max(-24,Math.min(24,Math.floor((n<=0?n+1:n-1)/3)*3))),is[8+n/3]};var ss=T(2),os=T(3),us=function(){return x},as=d3.map({linear:us,poly:T,quad:function(){return ss},cubic:function(){return os},sin:function(){return N},exp:function(){return C},circle:function(){return k},elastic:L,back:A,bounce:function(){return O}}),fs=d3.map({"in":x,out:E,"in-out":S,"out-in":function(e){return S(E(e))}});d3.ease=function(e){var t=e.indexOf("-"),n=t>=0?e.substring(0,t):e,r=t>=0?e.substring(t+1):"in";return n=as.get(n)||us,r=fs.get(r)||x,w(r(n.apply(null,Array.prototype.slice.call(arguments,1))))},d3.event=null,d3.transform=function(e){var t=document.createElementNS(d3.ns.prefix.svg,"g");return(d3.transform=function(e){t.setAttribute("transform",e);var n=t.transform.baseVal.consolidate();return new P(n?n.matrix:cs)})(e)},P.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var ls=180/Math.PI,cs={a:1,b:0,c:0,d:1,e:0,f:0};d3.interpolate=function(e,t){var n=d3.interpolators.length,r;while(--n>=0&&!(r=d3.interpolators[n](e,t)));return r},d3.interpolateNumber=function(e,t){return t-=e,function(n){return e+t*n}},d3.interpolateRound=function(e,t){return t-=e,function(n){return Math.round(e+t*n)}},d3.interpolateString=function(e,t){var n,r,i,s=0,o=0,u=[],a=[],f,l;hs.lastIndex=0;for(r=0;n=hs.exec(t);++r)n.index&&u.push(t.substring(s,o=n.index)),a.push({i:u.length,x:n[0]}),u.push(null),s=hs.lastIndex;s180?l+=360:l-f>180&&(f+=360),r.push({i:n.push(n.pop()+"rotate(",null,")")-2,x:d3.interpolateNumber(f,l)})):l&&n.push(n.pop()+"rotate("+l+")"),c!=h?r.push({i:n.push(n.pop()+"skewX(",null,")")-2,x:d3.interpolateNumber(c,h)}):h&&n.push(n.pop()+"skewX("+h+")"),p[0]!=d[0]||p[1]!=d[1]?(i=n.push(n.pop()+"scale(",null,",",null,")"),r.push({i:i-4,x:d3.interpolateNumber(p[0],d[0])},{i:i-2,x:d3.interpolateNumber(p[1],d[1])})):(d[0]!=1||d[1]!=1)&&n.push(n.pop()+"scale("+d+")"),i=r.length,function(e){var t=-1,s;while(++t180?s-=360:s<-180&&(s+=360),function(e){return Y(n+s*e,r+o*e,i+u*e)+""}},d3.interpolateLab=function(e,t){e=d3.lab(e),t=d3.lab(t);var n=e.l,r=e.a,i=e.b,s=t.l-n,o=t.a-r,u=t.b-i;return function(e){return it(n+s*e,r+o*e,i+u*e)+""}},d3.interpolateHcl=function(e,t){e=d3.hcl(e),t=d3.hcl(t);var n=e.h,r=e.c,i=e.l,s=t.h-n,o=t.c-r,u=t.l-i;return s>180?s-=360:s<-180&&(s+=360),function(e){return tt(n+s*e,r+o*e,i+u*e)+""}},d3.interpolateArray=function(e,t){var n=[],r=[],i=e.length,s=t.length,o=Math.min(e.length,t.length),u;for(u=0;u=0;)if(s=n[r])i&&i!==s.nextSibling&&i.parentNode.insertBefore(s,i),i=s;return this},ks.sort=function(e){e=wt.apply(this,arguments);for(var t=-1,n=this.length;++t=Zs?e?"M0,"+s+"A"+s+","+s+" 0 1,1 0,"+ -s+"A"+s+","+s+" 0 1,1 0,"+s+"M0,"+e+"A"+e+","+e+" 0 1,0 0,"+ -e+"A"+e+","+e+" 0 1,0 0,"+e+"Z":"M0,"+s+"A"+s+","+s+" 0 1,1 0,"+ -s+"A"+s+","+s+" 0 1,1 0,"+s+"Z":e?"M"+s*l+","+s*c+"A"+s+","+s+" 0 "+f+",1 "+s*h+","+s*p+"L"+e*h+","+e*p+"A"+e+","+e+" 0 "+f+",0 "+e*l+","+e*c+"Z":"M"+s*l+","+s*c+"A"+s+","+s+" 0 "+f+",1 "+s*h+","+s*p+"L0,0"+"Z"}var t=en,n=tn,r=nn,i=rn;return e.innerRadius=function(n){return arguments.length?(t=u(n),e):t},e.outerRadius=function(t){return arguments.length?(n=u(t),e):n},e.startAngle=function(t){return arguments.length?(r=u(t),e):r},e.endAngle=function(t){return arguments.length?(i=u(t),e):i},e.centroid=function(){var e=(t.apply(this,arguments)+n.apply(this,arguments))/2,s=(r.apply(this,arguments)+i.apply(this,arguments))/2+Ys;return[Math.cos(s)*e,Math.sin(s)*e]},e};var Ys=-Math.PI/2,Zs=2*Math.PI-1e-6;d3.svg.line=function(){return sn(i)};var eo=d3.map({linear:an,"linear-closed":fn,"step-before":ln,"step-after":cn,basis:gn,"basis-open":yn,"basis-closed":bn,bundle:wn,cardinal:dn,"cardinal-open":hn,"cardinal-closed":pn,monotone:Cn});eo.forEach(function(e,t){t.key=e,t.closed=/-closed$/.test(e)});var to=[0,2/3,1/3,0],no=[0,1/3,2/3,0],ro=[0,1/6,2/3,1/6];d3.svg.line.radial=function(){var e=sn(kn);return e.radius=e.x,delete e.x,e.angle=e.y,delete e.y,e},ln.reverse=cn,cn.reverse=ln,d3.svg.area=function(){return Ln(i)},d3.svg.area.radial=function(){var e=Ln(kn);return e.radius=e.x,delete e.x,e.innerRadius=e.x0,delete e.x0,e.outerRadius=e.x1,delete e.x1,e.angle=e.y,delete e.y,e.startAngle=e.y0,delete e.y0,e.endAngle=e.y1,delete e.y1,e},d3.svg.chord=function(){function e(e,u){var a=t(this,s,e,u),f=t(this,o,e,u);return"M"+a.p0+r(a.r,a.p1,a.a1-a.a0)+(n(a,f)?i(a.r,a.p1,a.r,a.p0):i(a.r,a.p1,f.r,f.p0)+r(f.r,f.p1,f.a1-f.a0)+i(f.r,f.p1,a.r,a.p0))+"Z"}function t(e,t,n,r){var i=t.call(e,n,r),s=a.call(e,i,r),o=f.call(e,i,r)+Ys,u=l.call(e,i,r)+Ys;return{r:s,a0:o,a1:u,p0:[s*Math.cos(o),s*Math.sin(o)],p1:[s*Math.cos(u),s*Math.sin(u)]}}function n(e,t){return e.a0==t.a0&&e.a1==t.a1}function r(e,t,n){return"A"+e+","+e+" 0 "+ +(n>Math.PI)+",1 "+t}function i(e,t,n,r){return"Q 0,0 "+r}var s=An,o=On,a=Mn,f=nn,l=rn;return e.radius=function(t){return arguments.length?(a=u(t),e):a},e.source=function(t){return arguments.length?(s=u(t),e):s},e.target=function(t){return arguments.length?(o=u(t),e):o},e.startAngle=function(t){return arguments.length?(f=u(t),e):f},e.endAngle=function(t){return arguments.length?(l=u(t),e):l},e},d3.svg.diagonal=function(){function e(e,i){var s=t.call(this,e,i),o=n.call(this,e,i),u=(s.y+o.y)/2,a=[s,{x:s.x,y:u},{x:o.x,y:u},o];return a=a.map(r),"M"+a[0]+"C"+a[1]+" "+a[2]+" "+a[3]}var t=An,n=On,r=Pn;return e.source=function(n){return arguments.length?(t=u(n),e):t},e.target=function(t){return arguments.length?(n=u(t),e):n},e.projection=function(t){return arguments.length?(r=t,e):r},e},d3.svg.diagonal.radial=function(){var e=d3.svg.diagonal(),t=Pn,n=e.projection;return e.projection=function(e){return arguments.length?n(Hn(t=e)):t},e},d3.svg.mouse=d3.mouse,d3.svg.touches=d3.touches,d3.svg.symbol=function(){function e(e,r){return(io.get(t.call(this,e,r))||Fn)(n.call(this,e,r))}var t=jn,n=Bn;return e.type=function(n){return arguments.length?(t=u(n),e):t},e.size=function(t){return arguments.length?(n=u(t),e):n},e};var io=d3.map({circle:Fn,cross:function(e){var t=Math.sqrt(e/5)/2;return"M"+ -3*t+","+ -t+"H"+ -t+"V"+ -3*t+"H"+t+"V"+ -t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+ -t+"V"+t+"H"+ -3*t+"Z"},diamond:function(e){var t=Math.sqrt(e/(2*oo)),n=t*oo;return"M0,"+ -t+"L"+n+",0"+" 0,"+t+" "+ -n+",0"+"Z"},square:function(e){var t=Math.sqrt(e)/2;return"M"+ -t+","+ -t+"L"+t+","+ -t+" "+t+","+t+" "+ -t+","+t+"Z"},"triangle-down":function(e){var t=Math.sqrt(e/so),n=t*so/2;return"M0,"+n+"L"+t+","+ -n+" "+ -t+","+ -n+"Z"},"triangle-up":function(e){var t=Math.sqrt(e/so),n=t*so/2;return"M0,"+ -n+"L"+t+","+n+" "+ -t+","+n+"Z"}});d3.svg.symbolTypes=io.keys();var so=Math.sqrt(3),oo=Math.tan(30*Math.PI/180);d3.svg.axis=function(){function e(e){e.each(function(){var e=d3.select(this),c=a==null?t.ticks?t.ticks.apply(t,u):t.domain():a,h=f==null?t.tickFormat?t.tickFormat.apply(t,u):String:f,p=Rn(t,c,l),d=e.selectAll(".minor").data(p,String),v=d.enter().insert("line","g").attr("class","tick minor").style("opacity",1e-6),m=d3.transition(d.exit()).style("opacity",1e-6).remove(),g=d3.transition(d).style("opacity",1),y=e.selectAll("g").data(c,String),b=y.enter().insert("g","path").style("opacity",1e-6),w=d3.transition(y.exit()).style("opacity",1e-6).remove(),E=d3.transition(y).style("opacity",1),S,x=Dt(t),T=e.selectAll(".domain").data([0]),N=T.enter().append("path").attr("class","domain"),C=d3.transition(T),k=t.copy(),L=this.__chart__||k;this.__chart__=k,b.append("line").attr("class","tick"),b.append("text");var A=b.select("line"),O=E.select("line"),M=y.select("text").text(h),_=b.select("text"),D=E.select("text");switch(n){case"bottom":S=In,v.attr("y2",i),g.attr("x2",0).attr("y2",i),A.attr("y2",r),_.attr("y",Math.max(r,0)+o),O.attr("x2",0).attr("y2",r),D.attr("x",0).attr("y",Math.max(r,0)+o),M.attr("dy",".71em").attr("text-anchor","middle"),C.attr("d","M"+x[0]+","+s+"V0H"+x[1]+"V"+s);break;case"top":S=In,v.attr("y2",-i),g.attr("x2",0).attr("y2",-i),A.attr("y2",-r),_.attr("y",-(Math.max(r,0)+o)),O.attr("x2",0).attr("y2",-r),D.attr("x",0).attr("y",-(Math.max(r,0)+o)),M.attr("dy","0em").attr("text-anchor","middle"),C.attr("d","M"+x[0]+","+ -s+"V0H"+x[1]+"V"+ -s);break;case"left":S=qn,v.attr("x2",-i),g.attr("x2",-i).attr("y2",0),A.attr("x2",-r),_.attr("x",-(Math.max(r,0)+o)),O.attr("x2",-r).attr("y2",0),D.attr("x",-(Math.max(r,0)+o)).attr("y",0),M.attr("dy",".32em").attr("text-anchor","end"),C.attr("d","M"+ -s+","+x[0]+"H0V"+x[1]+"H"+ -s);break;case"right":S=qn,v.attr("x2",i),g.attr("x2",i).attr("y2",0),A.attr("x2",r),_.attr("x",Math.max(r,0)+o),O.attr("x2",r).attr("y2",0),D.attr("x",Math.max(r,0)+o).attr("y",0),M.attr("dy",".32em").attr("text-anchor","start"),C.attr("d","M"+s+","+x[0]+"H0V"+x[1]+"H"+s)}if(t.ticks)b.call(S,L),E.call(S,k),w.call(S,k),v.call(S,L),g.call(S,k),m.call(S,k);else{var P=k.rangeBand()/2,H=function(e){return k(e)+P};b.call(S,H),E.call(S,H)}})}var t=d3.scale.linear(),n="bottom",r=6,i=6,s=6,o=3,u=[10],a=null,f,l=0;return e.scale=function(n){return arguments.length?(t=n,e):t},e.orient=function(t){return arguments.length?(n=t,e):n},e.ticks=function(){return arguments.length?(u=arguments,e):u},e.tickValues=function(t){return arguments.length?(a=t,e):a},e.tickFormat=function(t){return arguments.length?(f=t,e):f},e.tickSize=function(t,n,o){if(!arguments.length)return r;var u=arguments.length-1;return r=+t,i=u>1?+n:r,s=u>0?+arguments[u]:r,e},e.tickPadding=function(t){return arguments.length?(o=+t,e):o},e.tickSubdivide=function(t){return arguments.length?(l=+t,e):l},e},d3.svg.brush=function(){function e(s){s.each(function(){var s=d3.select(this),f=s.selectAll(".background").data([0]),l=s.selectAll(".extent").data([0]),c=s.selectAll(".resize").data(a,String),h;s.style("pointer-events","all").on("mousedown.brush",i).on("touchstart.brush",i),f.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),l.enter().append("rect").attr("class","extent").style("cursor","move"),c.enter().append("g").attr("class",function(e){return"resize "+e}).style("cursor",function(e){return uo[e]}).append("rect").attr("x",function(e){return/[ew]$/.test(e)?-3:null}).attr("y",function(e){return/^[ns]/.test(e)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),c.style("display",e.empty()?"none":null),c.exit().remove(),o&&(h=Dt(o),f.attr("x",h[0]).attr("width",h[1]-h[0]),n(s)),u&&(h=Dt(u),f.attr("y",h[0]).attr("height",h[1]-h[0]),r(s)),t(s)})}function t(e){e.selectAll(".resize").attr("transform",function(e){return"translate("+f[+/e$/.test(e)][0]+","+f[+/^s/.test(e)][1]+")"})}function n(e){e.select(".extent").attr("x",f[0][0]),e.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1][0]-f[0][0])}function r(e){e.select(".extent").attr("y",f[0][1]),e.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1][1]-f[0][1])}function i(){function i(){var e=d3.event.changedTouches;return e?d3.touches(v,e)[0]:d3.mouse(v)}function a(){d3.event.keyCode==32&&(S||(x=null,T[0]-=f[1][0],T[1]-=f[1][1],S=2),M())}function c(){d3.event.keyCode==32&&S==2&&(T[0]+=f[1][0],T[1]+=f[1][1],S=0,M())}function h(){var e=i(),s=!1;N&&(e[0]+=N[0],e[1]+=N[1]),S||(d3.event.altKey?(x||(x=[(f[0][0]+f[1][0])/2,(f[0][1]+f[1][1])/2]),T[0]=f[+(e[0]0?a=e:a=0:e>0&&(r.start({type:"start",alpha:a=e}),d3.timer(n.tick)),n):a},n.start=function(){function e(e,n){var i=t(r),s=-1,o=i.length,u;while(++si&&(i=u),r.push(u)}for(o=0;o0){s=-1;while(++s=a[0]&&d<=a[1]&&(l=o[d3.bisect(f,d,1,h)-1],l.y+=p,l.push(e[s]))}return o}var t=!0,n=Number,r=fr,i=ur;return e.value=function(t){return arguments.length?(n=t,e):n},e.range=function(t){return arguments.length?(r=u(t),e):r},e.bins=function(t){return arguments.length?(i=typeof t=="number"?function(e){return ar(e,t)}:u(t),e):i},e.frequency=function(n){return arguments.length?(t=!!n,e):t},e},d3.layout.hierarchy=function(){function e(t,o,u){var a=i.call(n,t,o),f=vo?t:{data:t};f.depth=o,u.push(f);if(a&&(c=a.length)){var l=-1,c,h=f.children=[],p=0,d=o+1,v;while(++l0){var l=n*f/2;Hr(o,function(e){e.r+=l}),Hr(o,br),Hr(o,function(e){e.r-=l}),f=Math.max(2*o.r/u,2*o.r/a)}return Sr(o,u/2,a/2,1/f),s}var t=d3.layout.hierarchy().sort(vr),n=0,r=[1,1];return e.size=function(t){return arguments.length?(r=t,e):r},e.padding=function(t){return arguments.length?(n=+t,e):n},lr(e,t)},d3.layout.cluster=function(){function e(e,i){var s=t.call(this,e,i),o=s[0],u,a=0,f,l;Hr(o,function(e){var t=e.children;t&&t.length?(e.x=Nr(t),e.y=Tr(t)):(e.x=u?a+=n(e,u):0,e.y=0,u=e)});var c=Cr(o),h=kr(o),p=c.x-n(c,h)/2,d=h.x+n(h,c)/2;return Hr(o,function(e){e.x=(e.x-p)/(d-p)*r[0],e.y=(1-(o.y?e.y/o.y:1))*r[1]}),s}var t=d3.layout.hierarchy().sort(null).value(null),n=Lr,r=[1,1];return e.separation=function(t){return arguments.length?(n=t,e):n},e.size=function(t){return arguments.length?(r=t,e):r},lr(e,t)},d3.layout.tree=function(){function e(e,i){function s(e,t){var r=e.children,i=e._tree;if(r&&(o=r.length)){var o,a=r[0],f,l=a,c,h=-1;while(++h0&&(jr(Fr(o,e,r),e,h),a+=h,f+=h),l+=o._tree.mod,a+=i._tree.mod,c+=u._tree.mod,f+=s._tree.mod;o&&!Or(s)&&(s._tree.thread=o,s._tree.mod+=l-f),i&&!Ar(u)&&(u._tree.thread=i,u._tree.mod+=a-c,r=e)}return r}var a=t.call(this,e,i),f=a[0];Hr(f,function(e,t){e._tree={ancestor:e,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),s(f),o(f,-f._tree.prelim);var l=Mr(f,Dr),c=Mr(f,_r),h=Mr(f,Pr),p=l.x-n(l,c)/2,d=c.x+n(c,l)/2,v=h.depth||1;return Hr(f,function(e){e.x=(e.x-p)/(d-p)*r[0],e.y=e.depth/v*r[1],delete e._tree}),a}var t=d3.layout.hierarchy().sort(null).value(null),n=Lr,r=[1,1];return e.separation=function(t){return arguments.length?(n=t,e):n},e.size=function(t){return arguments.length?(r=t,e):r},lr(e,t)},d3.layout.treemap=function(){function e(e,t){var n=-1,r=e.length,i,s;while(++n0)u.push(f=a[d-1]),u.area+=f.area,(h=r(u,p))<=c?(a.pop(),c=h):(u.area-=u.pop().area,i(u,p,o,!1),p=Math.min(o.dx,o.dy),u.length=u.area=0,c=Infinity);u.length&&(i(u,p,o,!0),u.length=u.area=0),s.forEach(t)}}function n(t){var r=t.children;if(r&&r.length){var s=l(t),o=r.slice(),u,a=[];e(o,s.dx*s.dy/t.value),a.area=0;while(u=o.pop())a.push(u),a.area+=u.area,u.z!=null&&(i(a,u.z?s.dx:s.dy,s,!o.length),a.length=a.area=0);r.forEach(n)}}function r(e,t){var n=e.area,r,i=0,s=Infinity,o=-1,u=e.length;while(++oi&&(i=r)}return n*=n,t*=t,n?Math.max(t*i*p/n,n/(t*s*p)):Infinity}function i(e,t,n,r){var i=-1,s=e.length,o=n.x,a=n.y,f=t?u(e.area/t):0,l;if(t==n.dx){if(r||f>n.dy)f=n.dy;while(++in.dx)f=n.dx;while(++i50?n:s<-140?r:o<21?i:t)(e)}var t=d3.geo.albers(),n=d3.geo.albers().origin([-160,60]).parallels([55,65]),r=d3.geo.albers().origin([-160,20]).parallels([8,18]),i=d3.geo.albers().origin([-60,10]).parallels([8,18]);return e.scale=function(s){return arguments.length?(t.scale(s),n.scale(s*.6),r.scale(s),i.scale(s*1.5),e.translate(t.translate())):t.scale()},e.translate=function(s){if(!arguments.length)return t.translate();var o=t.scale()/1e3,u=s[0],a=s[1];return t.translate(s),n.translate([u-400*o,a+170*o]),r.translate([u-190*o,a+200*o]),i.translate([u+580*o,a+430*o]),e},e.scale(t.scale())},d3.geo.bonne=function(){function e(e){var u=e[0]*mo-r,a=e[1]*mo-i;if(s){var f=o+s-a,l=u*Math.cos(a)/f;u=f*Math.sin(l),a=f*Math.cos(l)-o}else u*=Math.cos(a),a*=-1;return[t*u+n[0],t*a+n[1]]}var t=200,n=[480,250],r,i,s,o;return e.invert=function(e){var i=(e[0]-n[0])/t,u=(e[1]-n[1])/t;if(s){var a=o+u,f=Math.sqrt(i*i+a*a);u=o+s-f,i=r+f*Math.atan2(i,a)/Math.cos(u)}else u*=-1,i/=Math.cos(u);return[i/mo,u/mo]},e.parallel=function(t){return arguments.length?(o=1/Math.tan(s=t*mo),e):s/mo},e.origin=function(t){return arguments.length?(r=t[0]*mo,i=t[1]*mo,e):[r/mo,i/mo]},e.scale=function(
+n){return arguments.length?(t=+n,e):t},e.translate=function(t){return arguments.length?(n=[+t[0],+t[1]],e):n},e.origin([0,0]).parallel(45)},d3.geo.equirectangular=function(){function e(e){var r=e[0]/360,i=-e[1]/360;return[t*r+n[0],t*i+n[1]]}var t=500,n=[480,250];return e.invert=function(e){var r=(e[0]-n[0])/t,i=(e[1]-n[1])/t;return[360*r,-360*i]},e.scale=function(n){return arguments.length?(t=+n,e):t},e.translate=function(t){return arguments.length?(n=[+t[0],+t[1]],e):n},e},d3.geo.mercator=function(){function e(e){var r=e[0]/360,i=-(Math.log(Math.tan(Math.PI/4+e[1]*mo/2))/mo)/360;return[t*r+n[0],t*Math.max(-0.5,Math.min(.5,i))+n[1]]}var t=500,n=[480,250];return e.invert=function(e){var r=(e[0]-n[0])/t,i=(e[1]-n[1])/t;return[360*r,2*Math.atan(Math.exp(-360*i*mo))/mo-90]},e.scale=function(n){return arguments.length?(t=+n,e):t},e.translate=function(t){return arguments.length?(n=[+t[0],+t[1]],e):n},e},d3.geo.path=function(){function e(e,t){typeof s=="function"&&(o=zr(s.apply(this,arguments))),f(e);var n=a.length?a.join(""):null;return a=[],n}function t(e){return u(e).join(",")}function n(e){var t=i(e[0]),n=0,r=e.length;while(++n0){a.push("M");while(++o0){a.push("M");while(++lr&&(r=e),si&&(i=s)}),[[t,n],[r,i]]};var go={Feature:Xr,FeatureCollection:Vr,GeometryCollection:$r,LineString:Jr,MultiLineString:Kr,MultiPoint:Jr,MultiPolygon:Qr,Point:Gr,Polygon:Yr};d3.geo.circle=function(){function e(){}function t(e){return a.distance(e)=l*l+c*c?r[s].index=-1:(r[h].index=-1,d=r[s].angle,h=s,p=o)):(d=r[s].angle,h=s,p=o);i.push(u);for(s=0,o=0;s<2;++o)r[o].index!==-1&&(i.push(r[o].index),s++);v=i.length;for(;o=0?(n=e.ep.r,r=e.ep.l):(n=e.ep.l,r=e.ep.r),e.a===1?(o=n?n.y:-1e6,i=e.c-e.b*o,u=r?r.y:1e6,s=e.c-e.b*u):(i=n?n.x:-1e6,o=e.c-e.a*i,s=r?r.x:1e6,u=e.c-e.a*s);var a=[i,o],f=[s,u];t[e.region.l.index].push(a,f),t[e.region.r.index].push(a,f)}),t.map(function(t,n){var r=e[n][0],i=e[n][1];return t.forEach(function(e){e.angle=Math.atan2(e[0]-r,e[1]-i)}),t.sort(function(e,t){return e.angle-t.angle}).filter(function(e,n){return!n||e.angle-t[n-1].angle>1e-10})})};var wo={l:"r",r:"l"};d3.geom.delaunay=function(e){var t=e.map(function(){return[]}),n=[];return ui(e,function(n){t[n.region.l.index].push(e[n.region.r.index])}),t.forEach(function(t,r){var i=e[r],s=i[0],o=i[1];t.forEach(function(e){e.angle=Math.atan2(e[0]-s,e[1]-o)}),t.sort(function(e,t){return e.angle-t.angle});for(var u=0,a=t.length-1;u=u,l=t.y>=a,c=(l<<1)+f;e.leaf=!1,e=e.nodes[c]||(e.nodes[c]=ai()),f?n=u:i=u,l?r=a:o=a,s(e,t,n,r,i,o)}var u,a=-1,f=e.length;f&&isNaN(e[0].x)&&(e=e.map(li));if(arguments.length<5)if(arguments.length===3)i=r=n,n=t;else{t=n=Infinity,r=i=-Infinity;while(++ar&&(r=u.x),u.y>i&&(i=u.y);var l=r-t,c=i-n;l>c?i=n+l:r=t+c}var h=ai();return h.add=function(e){s(h,e,t,n,r,i)},h.visit=function(e){fi(e,h,t,n,r,i)},e.forEach(h.add),h},d3.time={};var Eo=Date,So=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];ci.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){xo.setUTCDate.apply(this._,arguments)},setDay:function(){xo.setUTCDay.apply(this._,arguments)},setFullYear:function(){xo.setUTCFullYear.apply(this._,arguments)},setHours:function(){xo.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){xo.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){xo.setUTCMinutes.apply(this._,arguments)},setMonth:function(){xo.setUTCMonth.apply(this._,arguments)},setSeconds:function(){xo.setUTCSeconds.apply(this._,arguments)},setTime:function(){xo.setTime.apply(this._,arguments)}};var xo=Date.prototype,To="%a %b %e %H:%M:%S %Y",No="%m/%d/%y",Co="%H:%M:%S",ko=So,Lo=ko.map(hi),Ao=["January","February","March","April","May","June","July","August","September","October","November","December"],Oo=Ao.map(hi);d3.time.format=function(e){function t(t){var r=[],i=-1,s=0,o,u;while(++i=12?"PM":"AM"},S:function(e){return Mo(e.getSeconds())},U:function(e){return Mo(d3.time.sundayOfYear(e))},w:function(e){return e.getDay()},W:function(e){return Mo(d3.time.mondayOfYear(e))},x:d3.time.format(No),X:d3.time.format(Co),y:function(e){return Mo(e.getFullYear()%100)},Y:function(e){return Do(e.getFullYear()%1e4)},Z:Di,"%":function(e){return"%"}},Uo={a:mi,A:gi,b:yi,B:bi,c:wi,d:ki,e:ki,H:Li,I:Li,L:Mi,m:Ci,M:Ai,p:_i,S:Oi,x:Ei,X:Si,y:Ti,Y:xi},zo=/^\s*\d+/,Wo=d3.map({am:0,pm:1});d3.time.format.utc=function(e){function t(e){try{Eo=ci;var t=new Eo;return t._=e,n(t)}finally{Eo=Date}}var n=d3.time.format(e);return t.parse=function(e){try{Eo=ci;var t=n.parse(e);return t&&t._}finally{Eo=Date}},t.toString=n.toString,t};var Xo=d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");d3.time.format.iso=Date.prototype.toISOString?Pi:Xo,Pi.parse=function(e){var t=new Date(e);return isNaN(t)?null:t},Pi.toString=Xo.toString,d3.time.second=Hi(function(e){return new Eo(Math.floor(e/1e3)*1e3)},function(e,t){e.setTime(e.getTime()+Math.floor(t)*1e3)},function(e){return e.getSeconds()}),d3.time.seconds=d3.time.second.range,d3.time.seconds.utc=d3.time.second.utc.range,d3.time.minute=Hi(function(e){return new Eo(Math.floor(e/6e4)*6e4)},function(e,t){e.setTime(e.getTime()+Math.floor(t)*6e4)},function(e){return e.getMinutes()}),d3.time.minutes=d3.time.minute.range,d3.time.minutes.utc=d3.time.minute.utc.range,d3.time.hour=Hi(function(e){var t=e.getTimezoneOffset()/60;return new Eo((Math.floor(e/36e5-t)+t)*36e5)},function(e,t){e.setTime(e.getTime()+Math.floor(t)*36e5)},function(e){return e.getHours()}),d3.time.hours=d3.time.hour.range,d3.time.hours.utc=d3.time.hour.utc.range,d3.time.day=Hi(function(e){var t=new Eo(1970,0);return t.setFullYear(e.getFullYear(),e.getMonth(),e.getDate()),t},function(e,t){e.setDate(e.getDate()+t)},function(e){return e.getDate()-1}),d3.time.days=d3.time.day.range,d3.time.days.utc=d3.time.day.utc.range,d3.time.dayOfYear=function(e){var t=d3.time.year(e);return Math.floor((e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/864e5)},So.forEach(function(e,t){e=e.toLowerCase(),t=7-t;var n=d3.time[e]=Hi(function(e){return(e=d3.time.day(e)).setDate(e.getDate()-(e.getDay()+t)%7),e},function(e,t){e.setDate(e.getDate()+Math.floor(t)*7)},function(e){var n=d3.time.year(e).getDay();return Math.floor((d3.time.dayOfYear(e)+(n+t)%7)/7)-(n!==t)});d3.time[e+"s"]=n.range,d3.time[e+"s"].utc=n.utc.range,d3.time[e+"OfYear"]=function(e){var n=d3.time.year(e).getDay();return Math.floor((d3.time.dayOfYear(e)+(n+t)%7)/7)}}),d3.time.week=d3.time.sunday,d3.time.weeks=d3.time.sunday.range,d3.time.weeks.utc=d3.time.sunday.utc.range,d3.time.weekOfYear=d3.time.sundayOfYear,d3.time.month=Hi(function(e){return e=d3.time.day(e),e.setDate(1),e},function(e,t){e.setMonth(e.getMonth()+t)},function(e){return e.getMonth()}),d3.time.months=d3.time.month.range,d3.time.months.utc=d3.time.month.utc.range,d3.time.year=Hi(function(e){return e=d3.time.day(e),e.setMonth(0,1),e},function(e,t){e.setFullYear(e.getFullYear()+t)},function(e){return e.getFullYear()}),d3.time.years=d3.time.year.range,d3.time.years.utc=d3.time.year.utc.range;var Vo=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],$o=[[d3.time.second,1],[d3.time.second,5],[d3.time.second,15],[d3.time.second,30],[d3.time.minute,1],[d3.time.minute,5],[d3.time.minute,15],[d3.time.minute,30],[d3.time.hour,1],[d3.time.hour,3],[d3.time.hour,6],[d3.time.hour,12],[d3.time.day,1],[d3.time.day,2],[d3.time.week,1],[d3.time.month,1],[d3.time.month,3],[d3.time.year,1]],Jo=[[d3.time.format("%Y"),function(e){return!0}],[d3.time.format("%B"),function(e){return e.getMonth()}],[d3.time.format("%b %d"),function(e){return e.getDate()!=1}],[d3.time.format("%a %d"),function(e){return e.getDay()&&e.getDate()!=1}],[d3.time.format("%I %p"),function(e){return e.getHours()}],[d3.time.format("%I:%M"),function(e){return e.getMinutes()}],[d3.time.format(":%S"),function(e){return e.getSeconds()}],[d3.time.format(".%L"),function(e){return e.getMilliseconds()}]],Ko=d3.scale.linear(),Qo=qi(Jo);$o.year=function(e,t){return Ko.domain(e.map(Ui)).ticks(t).map(Ri)},d3.time.scale=function(){return ji(d3.scale.linear(),$o,Qo)};var Go=$o.map(function(e){return[e[0].utc,e[1]]}),Yo=[[d3.time.format.utc("%Y"),function(e){return!0}],[d3.time.format.utc("%B"),function(e){return e.getUTCMonth()}],[d3.time.format.utc("%b %d"),function(e){return e.getUTCDate()!=1}],[d3.time.format.utc("%a %d"),function(e){return e.getUTCDay()&&e.getUTCDate()!=1}],[d3.time.format.utc("%I %p"),function(e){return e.getUTCHours()}],[d3.time.format.utc("%I:%M"),function(e){return e.getUTCMinutes()}],[d3.time.format.utc(":%S"),function(e){return e.getUTCSeconds()}],[d3.time.format.utc(".%L"),function(e){return e.getUTCMilliseconds()}]],Zo=qi(Yo);Go.year=function(e,t){return Ko.domain(e.map(Wi)).ticks(t).map(zi)},d3.time.scale.utc=function(){return ji(d3.scale.linear(),Go,Zo)}})();
\ No newline at end of file