From 6d07b7f45d71f700fe1dd6e0ffdde9a723403047 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 23 Oct 2012 16:41:16 -0400 Subject: [PATCH] Start on the newest megapull This one swaps out dojo entirely. I wish that there was a way to divide tasks between dojo and nojo, but the module loader system makes this more or less impossible, or at least incredibly annoying. --- css/app.css | 20 - index.html | 141 ++--- js/iD/Connection.js | 4 - js/iD/Controller.js | 2 +- js/iD/renderer/EntityUI.js | 232 ++++---- js/iD/renderer/Map.js | 891 +++++++++++++++--------------- js/iD/renderer/NodeUI.js | 175 +++--- js/iD/renderer/WayUI.js | 16 +- js/iD/renderer/renderer.js | 1 + js/iD/styleparser/Condition.js | 13 +- js/iD/styleparser/Rule.js | 84 ++- js/iD/styleparser/RuleChain.js | 109 ++-- js/iD/styleparser/RuleSet.js | 747 +++++++++++++------------ js/iD/styleparser/Style.js | 46 +- js/iD/styleparser/StyleChooser.js | 21 +- js/iD/styleparser/StyleList.js | 26 +- js/iD/styleparser/styleparser.js | 1 + js/lib/d3.v2.min.js | 4 + 18 files changed, 1206 insertions(+), 1327 deletions(-) create mode 100644 js/iD/renderer/renderer.js create mode 100644 js/iD/styleparser/styleparser.js create mode 100644 js/lib/d3.v2.min.js diff --git a/css/app.css b/css/app.css index 80010a180..78fd11a53 100644 --- a/css/app.css +++ b/css/app.css @@ -25,12 +25,6 @@ input[type=text]:focus { border-color:#222; } -* { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - text { -webkit-user-select: none; -moz-user-select: none; @@ -44,16 +38,6 @@ table th { text-align:left; } -#map { - height: 600px; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - .help-pane { position:absolute; left:0; @@ -146,10 +130,6 @@ table th { width:135px; } -polyline { - cursor: pointer; -} - .edit-pane { position:absolute; display:none; diff --git a/index.html b/index.html index 49575e610..f5f5b8238 100755 --- a/index.html +++ b/index.html @@ -2,37 +2,95 @@ - iD -
+ + + + + + + + + + + + + + + + - - -
- - - -
- -
-
-
- -
- -
- - -
-
Click on the map to start a road
-
Draw the road by clicking on points along its path
-
Choose a road type
-
- - -
-

 

- × -
- - - - - - - - - -
KeyValue
-
-
-
-
- - - -
-
-

Work in progress: introduction, code, docs. Imagery © 2012 Bing, GeoEye, Getmapping, Intermap, Microsoft.

- - diff --git a/js/iD/Connection.js b/js/iD/Connection.js index bfd2b95c6..d6018611e 100755 --- a/js/iD/Connection.js +++ b/js/iD/Connection.js @@ -1,7 +1,3 @@ -// define(["dojo/_base/xhr","dojo/_base/lang","dojox/xml/DomParser","dojo/_base/array",'dojo/_base/declare', -// "iD/Entity","iD/Node","iD/Way","iD/Relation","iD/actions/CreateEntityAction"], -// function(xhr,lang,DomParser,array,declare,Entity){ - // ---------------------------------------------------------------------- // Connection base class diff --git a/js/iD/Controller.js b/js/iD/Controller.js index 3588bca20..e532f9c86 100755 --- a/js/iD/Controller.js +++ b/js/iD/Controller.js @@ -7,7 +7,7 @@ iD.Controller = function(map) { controller.editorCache = {}; controller.undoStack = new iD.UndoStack(); - controller.stepper = new iD.ui.StepPane(); + // controller.stepper = new iD.ui.StepPane(); controller.setState = function(newState) { // summary: Enter a new ControllerState, firing exitState on the old one, and enterState on the new one. diff --git a/js/iD/renderer/EntityUI.js b/js/iD/renderer/EntityUI.js index b6541bddc..38be5bf47 100755 --- a/js/iD/renderer/EntityUI.js +++ b/js/iD/renderer/EntityUI.js @@ -7,128 +7,120 @@ // fill images // opacity -define(['dojo/_base/declare','iD/Entity','iD/renderer/Map'], -function(declare) { +// ---------------------------------------------------------------------- +// EntityUI base class - // ---------------------------------------------------------------------- - // EntityUI base class +iD.renderer.EntityUI = function() { + this.entity=entity; + this.map=map; + this.stateClasses=stateClasses ? stateClasses.slice() : []; + this.sprites=[]; +}; +iD.renderer.EntityUI.prototype = { - declare("iD.renderer.EntityUI", null, { + entity:null, // Entity this represents + map:null, // the Map object containing this + layer:0, // OSM layer + sprites:null, // array of sprites created for this EntityUI + styleList:null, // current StyleList + stateClasses:null, // list of stateClass tags to apply - entity:null, // Entity this represents - map:null, // the Map object containing this - layer:0, // OSM layer - sprites:null, // array of sprites created for this EntityUI - styleList:null, // current StyleList - stateClasses:null, // list of stateClass tags to apply - - constructor: function(entity,map,stateClasses) { - // summary: Base class for a UI representing an entity. - this.entity=entity; - this.map=map; - this.stateClasses=stateClasses ? stateClasses.slice() : []; - this.sprites=[]; - }, - getConnection: function() { - // summary: Get the Connection from where the map draws its data. - return this.map.connection; // iD.Connection - }, - targetGroup: function(groupType,sublayer) { - // summary: Find a gfx.Group to render on. - return this.map.sublayer(this.layer,groupType,sublayer); // dojox.gfx.Group - }, - recordSprite: function(sprite) { - // summary: Record that an individual sprite (one stroke, icon or text item) has been added. - if (!_.include(this.sprites, sprite)) { - this.sprites.push(sprite); - } - return sprite; - }, - removeSprites: function() { - // summary: Clear all sprites currently used. - for (var i=0; i-1) { - this.stateClasses.splice(this.stateClasses.indexOf(sc),1); - this.invalidateStyleList(); - } - return this; - }, - - hasStateClass:function(sc) { - // summary: Is a particular state class set for this UI? - return this.stateClasses.indexOf(sc) > -1; - }, - - invalidateStyleList:function() { - // summary: Invalidate the StyleList so it's recalculated on next redraw. - this.styleList = null; - }, - - // -------------------- - // Mouse event handling - - entityMouseEvent:function(event) { - // summary: Receive a mouse event (e.g. clicking on the UI), and forward it to the Controller. - this.map.controller.entityMouseEvent(event, event.gfxTarget.source); - event.stopPropagation(); + getConnection: function() { + // summary: Get the Connection from where the map draws its data. + return this.map.connection; // iD.Connection + }, + targetGroup: function(groupType,sublayer) { + // summary: Find a gfx.Group to render on. + return this.map.sublayer(this.layer,groupType,sublayer); // dojox.gfx.Group + }, + recordSprite: function(sprite) { + // summary: Record that an individual sprite (one stroke, icon or text item) has been added. + if (!_.include(this.sprites, sprite)) { + this.sprites.push(sprite); + } + return sprite; + }, + removeSprites: function() { + // summary: Clear all sprites currently used. + for (var i=0; i-1) { + this.stateClasses.splice(this.stateClasses.indexOf(sc),1); + this.invalidateStyleList(); + } + return this; + }, + + hasStateClass:function(sc) { + // summary: Is a particular state class set for this UI? + return this.stateClasses.indexOf(sc) > -1; + }, + + invalidateStyleList:function() { + // summary: Invalidate the StyleList so it's recalculated on next redraw. + this.styleList = null; + }, + + // -------------------- + // Mouse event handling + + entityMouseEvent:function(event) { + // summary: Receive a mouse event (e.g. clicking on the UI), and forward it to the Controller. + this.map.controller.entityMouseEvent(event, event.gfxTarget.source); + event.stopPropagation(); + } +}; diff --git a/js/iD/renderer/Map.js b/js/iD/renderer/Map.js index b637da53a..fc2fc2b54 100755 --- a/js/iD/renderer/Map.js +++ b/js/iD/renderer/Map.js @@ -1,513 +1,496 @@ // iD/renderer/Map.js // at present this combines P2's Map and MapPaint functionality -define(['dojo/_base/declare','dojo/_base/event', - 'dojo/dom-geometry', - 'dojox/gfx','dojox/gfx/matrix', - 'iD/Connection','iD/Entity','iD/renderer/EntityUI','iD/renderer/WayUI','iD/renderer/NodeUI'], -function(declare, Event, domGeom, Gfx, Matrix){ +// ---------------------------------------------------------------------- +// Connection base class - // ---------------------------------------------------------------------- - // Connection base class +iD.renderer.Map = 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. + this.mapwidth = obj.width ? obj.width : 800; + this.mapheight = obj.height ? obj.height : 400; - declare("iD.renderer.Map", null, { + // Initialise variables + this.uis = {}; - MASTERSCALE: 5825.4222222222, - MINSCALE: 14, - MAXSCALE: 23, - zoom: NaN, - zoomfactor: NaN, - baselon: NaN, // original longitude at top left of viewport - baselat: NaN, // original latitude at top left of viewport - baselatp: NaN, // original projected latitude at top left of viewport + this.surface = d3.selectAll(obj.selector) + .append('svg') + .attr('width', this.mapwidth) + .attr('height', this.mapwidth); - div: '', //
of this map - surface: null, //
.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: {}, + this.tilegroup = this.surface.append('g'); + this.container = this.surface.append('g'); + 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(); - 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 + // Cache the margin box, since this is expensive. + // this.marginBox = domGeom.getMarginBox(this.div); - 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 layers + this.layers={}; + for (var l=this.minlayer; l<=this.maxlayer; l++) { + var r = this.container.append('g'); + this.layers[l]={ + root: r, + fill: r.append('g'), + casing: r.append('g'), + stroke: r.append('g'), + text: r.append('g'), + hit: r.append('g') + }; + } - 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, // | + // Create group for elastic band + this.elastic = this.container.append('g'); - layers: null, // array-like object of Groups, one for each OSM layer - minlayer: -5, // minimum OSM layer supported - maxlayer: 5, // maximum OSM layer supported + // Make draggable + this.tilegroup.on('onmousedown', _.bind(this.startDrag, this)); + this.surface.on('onclick', _.bind(this.clickSurface, this)); + this.surface.on('onmousemove', _.bind(this.processMove, this)); + this.surface.on('onmousedown', _.bind(this._mouseEvent, this)); + this.surface.on('onmouseup', _.bind(this._mouseEvent, this)); +}; +iD.renderer.Map.prototype = { - elastic: null, // Group for drawing elastic band + MASTERSCALE: 5825.4222222222, + MINSCALE: 14, + MAXSCALE: 23, + zoom: NaN, + zoomfactor: NaN, + baselon: NaN, // original longitude at top left of viewport + baselat: NaN, // original latitude at top left of viewport + baselatp: NaN, // original projected latitude at top left of viewport - ruleset: null, // map style + div: '', //
of this map + surface: null, //
.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 (zoomthis.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