]> source.dussan.org Git - svg.js.git/commitdiff
Added marker, symbol and dynamic referencing
authorwout <wout@impinc.co.uk>
Tue, 17 Jun 2014 18:17:01 +0000 (20:17 +0200)
committerwout <wout@impinc.co.uk>
Tue, 17 Jun 2014 18:17:01 +0000 (20:17 +0200)
31 files changed:
CHANGELOG.md
README.md
Rakefile
bower.json
component.json
dist/svg.js
dist/svg.min.js
package.json
spec/index.html
spec/spec/defs.js [new file with mode: 0644]
spec/spec/element.js
spec/spec/helper.js
spec/spec/marker.js [new file with mode: 0644]
spec/spec/regex.js
spec/spec/selector.js [new file with mode: 0644]
spec/spec/set.js
spec/spec/svg.js
spec/spec/symbol.js [new file with mode: 0644]
spec/spec/text.js
src/defs.js
src/element.js
src/gradient.js
src/helpers.js
src/marker.js [new file with mode: 0644]
src/pattern.js
src/regex.js
src/selector.js [new file with mode: 0644]
src/set.js
src/svg.js
src/symbol.js [new file with mode: 0644]
src/text.js

index 7575f126d84ade722fa6c0609191f12ebd9cb612..cfb2d6128f4e94efdf9eb62741193664e03853fb 100755 (executable)
@@ -1,9 +1,25 @@
+# 1.0.0-rc.10 (27/06/2014)
+
+- remove internal references everywhere -> __TODO!__
+- rework transformation to be chainable and more true to native SVG -> __TODO!__
+- implement an SVG adoption system to be able to manipulate existing SVG's not created with svg.js -> __TODO!__
+- fixed a bug in clipping and masking where empty nodes persists after removal -> __TODO!__
+- fixed infinite loop in viewbox when element has a percentage width / height [thanks @shabegger] -> __TO MERGE!__
+
+# 1.0.0-rc.9 (17/06/2014)
+
+- added `SVG.Marker`
+- added `SVG.Symbol`
+- added `first()` and `last()` methods to `SVG.Set`
+- added `length()` method to `SVG.Text` and `SVG.TSpan` to calculate total text length
+- `SVG.get()` will now also fetch elements with a `xlink:href="#elementId"` or `url(#elementId)` value given
+- added `reference()` method to get referenced elements from a given attribute value
+
 # 1.0.0-rc.8 (12/06/2014)
 
 - fixed bug in `SVG.off`
 - fixed offset by window scroll position in `rbox()` [thanks @bryhoyt]
 
-
 # 1.0.0-rc.7 (11/06/2014)
 
 - calling `after()` when calling `stop(true)` (fulfill flag) [thanks @vird]
index 63baa6830fb8ecfa6a78ccf6d2c59f838977b843..01051337bf6356651eb6a13ca90f9bd91057c51e 100755 (executable)
--- a/README.md
+++ b/README.md
@@ -339,7 +339,7 @@ __`returns`: `itself`__
 The path string is similar to the polygon string but much more complex in order to support curves:
 
 ```javascript
-var path = draw.path('M10,20L30,40')
+draw.path('M 100 200 C 200 100 300  0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100')
 ```
 
 __`returns`: `SVG.Path`__
@@ -539,6 +539,16 @@ text.clear()
 
 __`returns`: `itself`__
 
+### length()
+Gets the total computed text length of all tspans together:
+
+```javascript
+text.length()
+```
+
+__`returns`: `number`__
+
+
 ### lines
 All added tspans are stored in the `lines` reference, which is an instance of `SVG.Set`.
 
@@ -641,6 +651,15 @@ tspan.clear()
 
 __`returns`: `itself`__
 
+### length()
+Gets the total computed text length:
+
+```javascript
+tspan.length()
+```
+
+__`returns`: `number`__
+
 ## TextPath
 A nice feature in svg is the ability to run text along a path:
 
@@ -891,6 +910,20 @@ draw.clear()
 __`returns`: `itself`__
 
 
+## Attribute references
+
+### reference()
+In cases where an element is linked to another element through an attribute, the linked element instance can be fetched with the `reference()` method. The only thing required is the attribute name:
+
+```javascript
+use.reference('href') //-> returns used element instance
+// or
+rect.reference('fill') //-> returns gradient instance
+// or
+circle.reference('clip-path') //-> returns clip instance
+```
+
+
 ## Manipulating elements
 
 ### attr()
@@ -2072,7 +2105,7 @@ set.index(rect) //-> -1 if element is not a member
 __`returns`: `number`__
 
 ### get()
-Get the element at a given index:
+Gets the element at a given index:
 
 ```javascript
 set.get(1)
@@ -2080,6 +2113,24 @@ set.get(1)
 
 __`returns`: `element`__
 
+### first()
+Gets the first element:
+
+```javascript
+set.first()
+```
+
+__`returns`: `element`__
+
+### last()
+Gets the last element:
+
+```javascript
+set.last()
+```
+
+__`returns`: `element`__
+
 ### bbox()
 Get the bounding box of all elements in the set:
 
@@ -2117,7 +2168,7 @@ set.animate(3000).fill('#ff0')
 __`returns`: `SVG.SetFX`__
 
 
-## Gradients
+## Gradient
 
 ### gradient()
 There are linear and radial gradients. The linear gradient can be created like this:
@@ -2251,7 +2302,7 @@ _This functionality requires the gradient.js module which is included in the def
 __`returns`: `value`__
 
 
-## Patterns
+## Pattern
 
 ### pattern()
 Creating a pattern is very similar to creating gradients
@@ -2303,6 +2354,62 @@ pattern.fill() //-> returns 'url(#SvgjsPattern1234)'
 __`returns`: `value`__
 
 
+## Marker
+
+### marker()
+Markers can be added to every individual point of a `line`, `polyline`, `polygon` and `path`. There are three types of markers: `start`, `mid` and `end`. Where `start` represents the first point, `end` the last and `mid` every point in between.
+
+```javascript
+var path = draw.path('M 100 200 C 200 100 300  0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100z')
+
+path.fill('none').stroke({ width: 1 })
+
+path.marker('start', 10, 10, function(add) {
+  add.circle(10).fill('#f06')
+})
+path.marker('mid', 10, 10, function(add) {
+  add.rect(10, 10)
+})
+path.marker('end', 20, 20, function(add) {
+  add.circle(6).center(4, 5)
+  add.circle(6).center(4, 15)
+  add.circle(6).center(16, 10)
+
+  this.fill('#0f6')
+})
+```
+
+The `marker()` method can be used in three ways. Firstly, a marker can be created on any container element (e.g. svg, nested, group, ...). This is useful if you plan to reuse the marker many times so it will create a marker in the defs but not show it yet:
+
+```javascript
+var marker = draw.marker(10, 10, function() {
+  add.rect(10, 10)
+})
+```
+
+Secondly a marker can be created and applied directly on its target element:
+
+```javascript
+path.marker('start', 10, 10, function() {
+  add.circle(10).fill('#f06')
+})
+```
+
+This will create a marker in the defs and apply it directly. Note that the first argument defines the position of the marker and that there are four arguments as opposed to three with the first example.
+
+Lastly, if a marker is created for reuse on a container element, it can be applied directly on the target element:
+
+```javascript
+path.marker('mid', marker)
+```
+
+Finally, to get a marker instance from the target element reference:
+
+```javascript
+path.reference('marker-end')
+```
+
+
 ## Data
 
 ### Setting
index 8acad71f2568888d410af5a54cfa3031445142ad..03d37f8e7cbec93e4b7c13c97a3a2a228a71352d 100755 (executable)
--- a/Rakefile
+++ b/Rakefile
@@ -1,7 +1,7 @@
-SVGJS_VERSION = '1.0.0-rc.8'
+SVGJS_VERSION = '1.0.0-rc.9'
 
 # all available modules in the correct loading order
-MODULES = %w[ svg inventor regex default color array pointarray patharray number viewbox bbox rbox element parent container fx relative event defs group arrange mask clip gradient pattern doc shape use rect ellipse line poly path image text textpath nested hyperlink sugar set data memory loader helpers ]
+MODULES = %w[ svg selector inventor regex default color array pointarray patharray number viewbox bbox rbox element parent container fx relative event defs group arrange mask clip gradient pattern doc shape symbol use rect ellipse line poly path image text textpath nested hyperlink marker sugar set data memory loader helpers ]
 
 # how many bytes in a "kilobyte"
 KILO = 1024
@@ -138,13 +138,6 @@ task :check_whitespace do
   fail if flunked
 end
 
-desc "Generate docco documentation from source files"
-task :docco do
-  verbose false do
-    sh 'docco', *Dir['src/*.js']
-  end
-end
-
 # svg.js version number + git sha if available
 def version_string
   desc = `git describe --tags HEAD 2>&1`.chomp
index 1cd7ce435fb22a062a33cf2bc1bd5b844a0f18b5..7ddcee43c3562dddc4e7965c7fb48455f3949ee1 100755 (executable)
@@ -1,6 +1,6 @@
 {
   "name": "svg.js",
-  "version":"1.0.0-rc.8",
+  "version":"1.0.0-rc.9",
   "homepage": "http://svgjs.com/",
   "authors": [
     "Wout Fierens <wout@impinc.co.uk>"
index d8d389da2975e95a8d4d601997afd4239900bd83..ebdd7c124ddb56ca5aeb06f4b4966c91bb81ef3d 100755 (executable)
@@ -2,7 +2,7 @@
   "name": "svg.js",
   "repo": "wout/svg.js",
   "description": "A lightweight library for manipulating and animating SVG",
-  "version": "1.0.0-rc.8",
+  "version": "1.0.0-rc.9",
   "keywords": ["svg"],
   "author": "Wout Fierens <wout@impinc.co.uk>",
   "main": "dist/svg.js",
index b3a832e43f66609add615073f7c3b7bc89a8e7cd..29d0711d164bb820dcee71d68a2f3976062e7bda 100755 (executable)
@@ -1,4 +1,4 @@
-/* svg.js 1.0.0-rc.8-3-g7eca094 - svg inventor regex default color array pointarray patharray number viewbox bbox rbox element parent container fx relative event defs group arrange mask clip gradient pattern doc shape use rect ellipse line poly path image text textpath nested hyperlink sugar set data memory loader helpers - svgjs.com/license */
+/* svg.js 1.0.0-rc.9 - svg selector inventor regex default color array pointarray patharray number viewbox bbox rbox element parent container fx relative event defs group arrange mask clip gradient pattern doc shape symbol use rect ellipse line poly path image text textpath nested hyperlink marker sugar set data memory loader helpers - svgjs.com/license */
 ;(function() {
 
   var SVG = this.SVG = function(element) {
       SVG.Set.inherit()
   }
   
-  // Method for getting an element by id
-  SVG.get = function(id) {
-    var node = document.getElementById(id)
-    if (node) return node.instance
-  }
-  
   // Initialize parsing element
   SVG.prepare = function(element) {
     /* select document body and create invisible svg element */
   if (!SVG.supported) return false
 
 
+  SVG.get = function(id) {
+    var node = document.getElementById(idFromReference(id) || id)
+    if (node) return node.instance
+  }
+
   SVG.invent = function(config) {
        /* create element initializer */
        var initializer = typeof config.create == 'function' ?
     
     /* parse rgb value */
   , rgb:          /rgb\((\d+),(\d+),(\d+)\)/
+    
+    /* parse reference id */
+  , reference:    /#([a-z0-9\-_]+)/i
   
     /* test hex value */
   , isHex:        /^#[a-f0-9]{3,6}$/i
     , size: function(width, height) {
         var p = proportionalSize(this.bbox(), width, height)
   
-        return this.attr({
-          width:  new SVG.Number(p.width)
-        , height: new SVG.Number(p.height)
-        })
+        return this
+          .width(new SVG.Number(p.width))
+          .height(new SVG.Number(p.height))
       }
       // Clone element
     , clone: function() {
         
         return this
       }
+      // Get / set id
+    , id: function(id) {
+        return this.attr('id', id)
+      }
       // Get bounding box
     , bbox: function() {
         return new SVG.BBox(this)
         }
         return this
       }
+      // Get referenced element form attribute value
+    , reference: function(attr) {
+        return SVG.get(this.attr(attr))
+      }
       // Private: find svg parent by instance
     , _parent: function(parent) {
         var element = this
   
     // Inherit from
   , inherit: SVG.Container
+    
   })
 
   SVG.G = SVG.invent({
       }
       // Return the fill id
     , fill: function() {
-        return 'url(#' + this.attr('id') + ')'
+        return 'url(#' + this.id() + ')'
       }
       // Alias string convertion to fill
     , toString: function() {
   , extend: {
       // Return the fill id
          fill: function() {
-           return 'url(#' + this.attr('id') + ')'
+           return 'url(#' + this.id() + ')'
          }
          // Update pattern by rebuilding
        , update: function(block) {
   
   })
 
+  SVG.Symbol = SVG.invent({
+    // Initialize node
+    create: 'symbol'
+  
+    // Inherit from
+  , inherit: SVG.Container
+  
+    // Add parent method
+  , construct: {
+      // Create a new symbol
+      symbol: function() {
+        return this.defs().put(new SVG.Symbol)
+      }
+    }
+    
+  })
+
   SVG.Use = SVG.invent({
     // Initialize node
     create: 'use'
       
       return this
     }
+    // Get length of text element
+  , length: function() {
+      return this.node.getComputedTextLength()
+    }
   })
   
   // Register rebuild event
     
   })
 
+  SVG.Marker = SVG.invent({
+    // Initialize node
+    create: 'marker'
+  
+    // Inherit from
+  , inherit: SVG.Container
+  
+    // Add class methods
+  , extend: {
+      // Set width of element
+      width: function(width) {
+        return this.attr('markerWidth', width)
+      }
+      // Set height of element
+    , height: function(height) {
+        return this.attr('markerHeight', height)
+      }
+      // Set marker refX and refY
+    , ref: function(x, y) {
+        return this.attr('refX', x).attr('refY', y)
+      }
+      // Update marker
+    , update: function(block) {
+        /* remove all content */
+        this.clear()
+        
+        /* invoke passed block */
+        if (typeof block == 'function')
+          block.call(this, this)
+        
+        return this
+      }
+      // Return the fill id
+    , toString: function() {
+        return 'url(#' + this.id() + ')'
+      }
+    }
+  
+    // Add parent method
+  , construct: {
+      marker: function(width, height, block) {
+        // Create marker element in defs
+        return this.defs().marker(width, height, block)
+      }
+    }
+  
+  })
+  
+  SVG.extend(SVG.Defs, {
+    // Create marker
+    marker: function(width, height, block) {
+      // Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto
+      return this.put(new SVG.Marker)
+        .size(width, height)
+        .ref(width / 2, height / 2)
+        .viewbox(0, 0, width, height)
+        .attr('orient', 'auto')
+        .update(block)
+    }
+    
+  })
+  
+  SVG.extend(SVG.Line, SVG.Polyline, SVG.Polygon, SVG.Path, {
+    // Create and attach markers
+    marker: function(marker, width, height, block) {
+      var attr = ['marker']
+  
+      // Build attribute name
+      if (marker != 'all') attr.push(marker)
+      attr = attr.join('-')
+  
+      // Set marker attribute
+      marker = arguments[1] instanceof SVG.Marker ?
+        arguments[1] :
+        this.doc().marker(width, height, block)
+      
+      return this.attr(attr, marker)
+    }
+    
+  })
+
   var sugar = {
     stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset']
   , fill:   ['color', 'opacity', 'rule']
     , get: function(i) {
         return this.members[i]
       }
+      // Get first member
+    , first: function() {
+        return this.get(0)
+      }
+      // Get last member
+    , last: function() {
+        return this.get(this.members.length - 1)
+      }
       // Default value
     , valueOf: function() {
         return this.members
     return o
   }
   
+  // Get id from reference string
+  function idFromReference(url) {
+    var m = url.toString().match(SVG.regex.reference)
+  
+    if (m) return m[1]
+  }
+  
   // Shim layer with setTimeout fallback by Paul Irish
   window.requestAnimFrame = (function(){
     return  window.requestAnimationFrame       ||
index f975b0cd597c9874959c8507da61d0ee6cc6d59f..8ee65fdba9780374f68530615c657f272ff86165 100755 (executable)
@@ -1,2 +1,2 @@
-(function(){function t(t){return t.toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()})}function e(t){return 4==t.length?["#",t.substring(1,2),t.substring(1,2),t.substring(2,3),t.substring(2,3),t.substring(3,4),t.substring(3,4)].join(""):t}function i(t){var e=t.toString(16);return 1==e.length?"0"+e:e}function n(t,e,i){return(null==e||null==i)&&(null==i?i=t.height/t.width*e:null==e&&(e=t.width/t.height*i)),{width:e,height:i}}function r(t,e){return"number"==typeof t.from?t.from+(t.to-t.from)*e:t instanceof a.Color||t instanceof a.Number?t.at(e):1>e?t.from:t.to}function s(t){for(var e=0,i=t.length,n="";i>e;e++)n+=t[e][0],null!=t[e][1]&&(n+=t[e][1],null!=t[e][2]&&(n+=" ",n+=t[e][2],null!=t[e][3]&&(n+=" ",n+=t[e][3],n+=" ",n+=t[e][4],null!=t[e][5]&&(n+=" ",n+=t[e][5],n+=" ",n+=t[e][6],null!=t[e][7]&&(n+=" ",n+=t[e][7])))));return n+" "}function h(t){t.x2=t.x+t.width,t.y2=t.y+t.height,t.cx=t.x+t.width/2,t.cy=t.y+t.height/2}function o(t){if(t.matrix){var e=t.matrix.replace(/\s/g,"").split(",");6==e.length&&(t.a=parseFloat(e[0]),t.b=parseFloat(e[1]),t.c=parseFloat(e[2]),t.d=parseFloat(e[3]),t.e=parseFloat(e[4]),t.f=parseFloat(e[5]))}return t}var a=this.SVG=function(t){return a.supported?(t=new a.Doc(t),a.parser||a.prepare(t),t):void 0};if(a.ns="http://www.w3.org/2000/svg",a.xmlns="http://www.w3.org/2000/xmlns/",a.xlink="http://www.w3.org/1999/xlink",a.did=1e3,a.eid=function(t){return"Svgjs"+t.charAt(0).toUpperCase()+t.slice(1)+a.did++},a.create=function(t){var e=document.createElementNS(this.ns,t);return e.setAttribute("id",this.eid(t)),e},a.extend=function(){var t,e,i,n;for(t=[].slice.call(arguments),e=t.pop(),n=t.length-1;n>=0;n--)if(t[n])for(i in e)t[n].prototype[i]=e[i];a.Set&&a.Set.inherit&&a.Set.inherit()},a.get=function(t){var e=document.getElementById(t);return e?e.instance:void 0},a.prepare=function(t){var e=document.getElementsByTagName("body")[0],i=(e?new a.Doc(e):t.nested()).size(2,0),n=a.create("path");i.node.appendChild(n),a.parser={body:e||t.parent,draw:i.style("opacity:0;position:fixed;left:100%;top:100%;overflow:hidden"),poly:i.polyline().node,path:n}},a.supported=function(){return!!document.createElementNS&&!!document.createElementNS(a.ns,"svg").createSVGRect}(),!a.supported)return!1;a.invent=function(t){var e="function"==typeof t.create?t.create:function(){this.constructor.call(this,a.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&a.extend(e,t.extend),t.construct&&a.extend(t.parent||a.Container,t.construct),e},a.regex={unit:/^(-?[\d\.]+)([a-z%]{0,2})$/,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^-?[\d\.]+$/,isPercent:/^-?[\d\.]+%$/,isImage:/\.(jpg|jpeg|png|gif)(\?[^=]+.*)?/i,isEvent:/^[\w]+:[\w]+$/},a.defaults={matrix:"1 0 0 1 0 0",attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"},trans:function(){return{x:0,y:0,scaleX:1,scaleY:1,rotation:0,skewX:0,skewY:0,matrix:this.matrix,a:1,b:0,c:0,d:1,e:0,f:0}}},a.Color=function(t){var i;this.r=0,this.g=0,this.b=0,"string"==typeof t?a.regex.isRgb.test(t)?(i=a.regex.rgb.exec(t.replace(/\s/g,"")),this.r=parseInt(i[1]),this.g=parseInt(i[2]),this.b=parseInt(i[3])):a.regex.isHex.test(t)&&(i=a.regex.hex.exec(e(t)),this.r=parseInt(i[1],16),this.g=parseInt(i[2],16),this.b=parseInt(i[3],16)):"object"==typeof t&&(this.r=t.r,this.g=t.g,this.b=t.b)},a.extend(a.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+i(this.r)+i(this.g)+i(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},morph:function(t){return this.destination=new a.Color(t),this},at:function(t){return this.destination?(t=0>t?0:t>1?1:t,new a.Color({r:~~(this.r+(this.destination.r-this.r)*t),g:~~(this.g+(this.destination.g-this.g)*t),b:~~(this.b+(this.destination.b-this.b)*t)})):this}}),a.Color.test=function(t){return t+="",a.regex.isHex.test(t)||a.regex.isRgb.test(t)},a.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},a.Color.isColor=function(t){return a.Color.isRgb(t)||a.Color.test(t)},a.Array=function(t,e){t=(t||[]).valueOf(),0==t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},a.extend(a.Array,{morph:function(t){if(this.destination=this.parse(t),this.value.length!=this.destination.length){for(var e=this.value[this.value.length-1],i=this.destination[this.destination.length-1];this.value.length>this.destination.length;)this.destination.push(i);for(;this.value.length<this.destination.length;)this.value.push(e)}return this},settle:function(){for(var t=0,e=this.value.length,i=[];e>t;t++)-1==i.indexOf(this.value[t])&&i.push(this.value[t]);return this.value=i},at:function(t){if(!this.destination)return this;for(var e=0,i=this.value.length,n=[];i>e;e++)n.push(this.value[e]+(this.destination[e]-this.value[e])*t);return new a.Array(n)},toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:this.split(t)},split:function(t){return t.replace(/\s+/g," ").replace(/^\s+|\s+$/g,"").split(" ")},reverse:function(){return this.value.reverse(),this}}),a.PointArray=function(){this.constructor.apply(this,arguments)},a.PointArray.prototype=new a.Array,a.extend(a.PointArray,{toString:function(){for(var t=0,e=this.value.length,i=[];e>t;t++)i.push(this.value[t].join(","));return i.join(" ")},at:function(t){if(!this.destination)return this;for(var e=0,i=this.value.length,n=[];i>e;e++)n.push([this.value[e][0]+(this.destination[e][0]-this.value[e][0])*t,this.value[e][1]+(this.destination[e][1]-this.value[e][1])*t]);return new a.PointArray(n)},parse:function(t){if(t=t.valueOf(),Array.isArray(t))return t;t=this.split(t);for(var e,i=0,n=t.length,r=[];n>i;i++)e=t[i].split(","),r.push([parseFloat(e[0]),parseFloat(e[1])]);return r},move:function(t,e){var i=this.bbox();if(t-=i.x,e-=i.y,!isNaN(t)&&!isNaN(e))for(var n=this.value.length-1;n>=0;n--)this.value[n]=[this.value[n][0]+t,this.value[n][1]+e];return this},size:function(t,e){var i,n=this.bbox();for(i=this.value.length-1;i>=0;i--)this.value[i][0]=(this.value[i][0]-n.x)*t/n.width+n.x,this.value[i][1]=(this.value[i][1]-n.y)*e/n.height+n.y;return this},bbox:function(){return a.parser.poly.setAttribute("points",this.toString()),a.parser.poly.getBBox()}}),a.PathArray=function(t,e){this.constructor.call(this,t,e)},a.PathArray.prototype=new a.Array,a.extend(a.PathArray,{toString:function(){return s(this.value)},move:function(t,e){var i=this.bbox();if(t-=i.x,e-=i.y,!isNaN(t)&&!isNaN(e))for(var n,r=this.value.length-1;r>=0;r--)n=this.value[r][0],"M"==n||"L"==n||"T"==n?(this.value[r][1]+=t,this.value[r][2]+=e):"H"==n?this.value[r][1]+=t:"V"==n?this.value[r][1]+=e:"C"==n||"S"==n||"Q"==n?(this.value[r][1]+=t,this.value[r][2]+=e,this.value[r][3]+=t,this.value[r][4]+=e,"C"==n&&(this.value[r][5]+=t,this.value[r][6]+=e)):"A"==n&&(this.value[r][6]+=t,this.value[r][7]+=e);return this},size:function(t,e){var i,n,r=this.bbox();for(i=this.value.length-1;i>=0;i--)n=this.value[i][0],"M"==n||"L"==n||"T"==n?(this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x,this.value[i][2]=(this.value[i][2]-r.y)*e/r.height+r.y):"H"==n?this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x:"V"==n?this.value[i][1]=(this.value[i][1]-r.y)*e/r.height+r.y:"C"==n||"S"==n||"Q"==n?(this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x,this.value[i][2]=(this.value[i][2]-r.y)*e/r.height+r.y,this.value[i][3]=(this.value[i][3]-r.x)*t/r.width+r.x,this.value[i][4]=(this.value[i][4]-r.y)*e/r.height+r.y,"C"==n&&(this.value[i][5]=(this.value[i][5]-r.x)*t/r.width+r.x,this.value[i][6]=(this.value[i][6]-r.y)*e/r.height+r.y)):"A"==n&&(this.value[i][1]=this.value[i][1]*t/r.width,this.value[i][2]=this.value[i][2]*e/r.height,this.value[i][6]=(this.value[i][6]-r.x)*t/r.width+r.x,this.value[i][7]=(this.value[i][7]-r.y)*e/r.height+r.y);return this},parse:function(t){if(t instanceof a.PathArray)return t.valueOf();var e,i,n,r,h,o,u,l,c,f,d,p=0,x=0;for(a.parser.path.setAttribute("d","string"==typeof t?t:s(t)),d=a.parser.path.pathSegList,e=0,i=d.numberOfItems;i>e;++e)f=d.getItem(e),c=f.pathSegTypeAsLetter,"M"==c||"L"==c||"H"==c||"V"==c||"C"==c||"S"==c||"Q"==c||"T"==c||"A"==c?("x"in f&&(p=f.x),"y"in f&&(x=f.y)):("x1"in f&&(h=p+f.x1),"x2"in f&&(u=p+f.x2),"y1"in f&&(o=x+f.y1),"y2"in f&&(l=x+f.y2),"x"in f&&(p+=f.x),"y"in f&&(x+=f.y),"m"==c?d.replaceItem(a.parser.path.createSVGPathSegMovetoAbs(p,x),e):"l"==c?d.replaceItem(a.parser.path.createSVGPathSegLinetoAbs(p,x),e):"h"==c?d.replaceItem(a.parser.path.createSVGPathSegLinetoHorizontalAbs(p),e):"v"==c?d.replaceItem(a.parser.path.createSVGPathSegLinetoVerticalAbs(x),e):"c"==c?d.replaceItem(a.parser.path.createSVGPathSegCurvetoCubicAbs(p,x,h,o,u,l),e):"s"==c?d.replaceItem(a.parser.path.createSVGPathSegCurvetoCubicSmoothAbs(p,x,u,l),e):"q"==c?d.replaceItem(a.parser.path.createSVGPathSegCurvetoQuadraticAbs(p,x,h,o),e):"t"==c?d.replaceItem(a.parser.path.createSVGPathSegCurvetoQuadraticSmoothAbs(p,x),e):"a"==c?d.replaceItem(a.parser.path.createSVGPathSegArcAbs(p,x,f.r1,f.r2,f.angle,f.largeArcFlag,f.sweepFlag),e):("z"==c||"Z"==c)&&(p=n,x=r)),("M"==c||"m"==c)&&(n=p,r=x);for(t=[],d=a.parser.path.pathSegList,e=0,i=d.numberOfItems;i>e;++e)f=d.getItem(e),c=f.pathSegTypeAsLetter,p=[c],"M"==c||"L"==c||"T"==c?p.push(f.x,f.y):"H"==c?p.push(f.x):"V"==c?p.push(f.y):"C"==c?p.push(f.x1,f.y1,f.x2,f.y2,f.x,f.y):"S"==c?p.push(f.x2,f.y2,f.x,f.y):"Q"==c?p.push(f.x1,f.y1,f.x,f.y):"A"==c&&p.push(f.r1,f.r2,f.angle,0|f.largeArcFlag,0|f.sweepFlag,f.x,f.y),t.push(p);return t},bbox:function(){return a.parser.path.setAttribute("d",this.toString()),a.parser.path.getBBox()}}),a.Number=function(t){if(this.value=0,this.unit="","number"==typeof t)this.value=isNaN(t)?0:isFinite(t)?t:0>t?-3.4e38:3.4e38;else if("string"==typeof t){var e=t.match(a.regex.unit);e&&(this.value=parseFloat(e[1]),"%"==e[2]?this.value/=100:"s"==e[2]&&(this.value*=1e3),this.unit=e[2])}else t instanceof a.Number&&(this.value=t.value,this.unit=t.unit)},a.extend(a.Number,{toString:function(){return("%"==this.unit?~~(1e8*this.value)/1e6:"s"==this.unit?this.value/1e3:this.value)+this.unit},valueOf:function(){return this.value},plus:function(t){return this.value=this+new a.Number(t),this},minus:function(t){return this.plus(-new a.Number(t))},times:function(t){return this.value=this*new a.Number(t),this},divide:function(t){return this.value=this/new a.Number(t),this},to:function(t){return"string"==typeof t&&(this.unit=t),this},morph:function(t){return this.destination=new a.Number(t),this},at:function(t){return this.destination?new a.Number(this.destination).minus(this).times(t).plus(this):this}}),a.ViewBox=function(t){var e,i,n,r,s=1,h=1,o=t.bbox(),u=(t.attr("viewBox")||"").match(/-?[\d\.]+/g);for(n=new a.Number(t.width()),r=new a.Number(t.height());"%"==n.unit;)s*=n.value,n=new a.Number(t instanceof a.Doc?t.parent.offsetWidth:t.width());for(;"%"==r.unit;)h*=r.value,r=new a.Number(t instanceof a.Doc?t.parent.offsetHeight:t.height());this.x=o.x,this.y=o.y,this.width=n*s,this.height=r*h,this.zoom=1,u&&(e=parseFloat(u[0]),i=parseFloat(u[1]),n=parseFloat(u[2]),r=parseFloat(u[3]),this.zoom=this.width/this.height>n/r?this.height/r:this.width/n,this.x=e,this.y=i,this.width=n,this.height=r)},a.extend(a.ViewBox,{toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height}}),a.BBox=function(t){var e;if(this.x=0,this.y=0,this.width=0,this.height=0,t){try{e=t.node.getBBox()}catch(i){e={x:t.node.clientLeft,y:t.node.clientTop,width:t.node.clientWidth,height:t.node.clientHeight}}this.x=e.x+t.trans.x,this.y=e.y+t.trans.y,this.width=e.width*t.trans.scaleX,this.height=e.height*t.trans.scaleY}h(this)},a.extend(a.BBox,{merge:function(t){var e=new a.BBox;return e.x=Math.min(this.x,t.x),e.y=Math.min(this.y,t.y),e.width=Math.max(this.x+this.width,t.x+t.width)-e.x,e.height=Math.max(this.y+this.height,t.y+t.height)-e.y,h(e),e}}),a.RBox=function(t){var e,i,n={};if(this.x=0,this.y=0,this.width=0,this.height=0,t){for(e=t.doc().parent,i=t.doc().viewbox().zoom,n=t.node.getBoundingClientRect(),this.x=n.left,this.y=n.top,this.x-=e.offsetLeft,this.y-=e.offsetTop;e=e.offsetParent;)this.x-=e.offsetLeft,this.y-=e.offsetTop;for(e=t;e=e.parent;)"svg"==e.type&&e.viewbox&&(i*=e.viewbox().zoom,this.x-=e.x()||0,this.y-=e.y()||0)}this.x/=i,this.y/=i,this.width=n.width/=i,this.height=n.height/=i,this.x+=window.scrollX,this.y+=window.scrollY,h(this)},a.extend(a.RBox,{merge:function(t){var e=new a.RBox;return e.x=Math.min(this.x,t.x),e.y=Math.min(this.y,t.y),e.width=Math.max(this.x+this.width,t.x+t.width)-e.x,e.height=Math.max(this.y+this.height,t.y+t.height)-e.y,h(e),e}}),a.Element=a.invent({create:function(t){this._stroke=a.defaults.attrs.stroke,this.trans=a.defaults.trans(),(this.node=t)&&(this.type=t.nodeName,this.node.instance=this)},extend:{x:function(t){return null!=t&&(t=new a.Number(t),t.value/=this.trans.scaleX),this.attr("x",t)},y:function(t){return null!=t&&(t=new a.Number(t),t.value/=this.trans.scaleY),this.attr("y",t)},cx:function(t){return null==t?this.x()+this.width()/2:this.x(t-this.width()/2)},cy:function(t){return null==t?this.y()+this.height()/2:this.y(t-this.height()/2)},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},width:function(t){return this.attr("width",t)},height:function(t){return this.attr("height",t)},size:function(t,e){var i=n(this.bbox(),t,e);return this.attr({width:new a.Number(i.width),height:new a.Number(i.height)})},clone:function(){var t,e,i=this.type;return t="rect"==i||"ellipse"==i?this.parent[i](0,0):"line"==i?this.parent[i](0,0,0,0):"image"==i?this.parent[i](this.src):"text"==i?this.parent[i](this.content):"path"==i?this.parent[i](this.attr("d")):"polyline"==i||"polygon"==i?this.parent[i](this.attr("points")):"g"==i?this.parent.group():this.parent[i](),e=this.attr(),delete e.id,t.attr(e),t.trans=this.trans,t.transform({})},remove:function(){return this.parent&&this.parent.removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return t.put(this)},putIn:function(t){return t.add(this)},doc:function(t){return this._parent(t||a.Doc)},attr:function(t,e,i){if(null==t){for(t={},e=this.node.attributes,i=e.length-1;i>=0;i--)t[e[i].nodeName]=a.regex.isNumber.test(e[i].nodeValue)?parseFloat(e[i].nodeValue):e[i].nodeValue;return t}if("object"==typeof t)for(e in t)this.attr(e,t[e]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return e=this.node.getAttribute(t),null==e?a.defaults.attrs[t]:a.regex.isNumber.test(e)?parseFloat(e):e;if("style"==t)return this.style(e);"stroke-width"==t?this.attr("stroke",parseFloat(e)>0?this._stroke:null):"stroke"==t&&(this._stroke=e),("fill"==t||"stroke"==t)&&(a.regex.isImage.test(e)&&(e=this.doc().defs().image(e,0,0)),e instanceof a.Image&&(e=this.doc().defs().pattern(0,0,function(){this.add(e)}))),"number"==typeof e?e=new a.Number(e):a.Color.isColor(e)?e=new a.Color(e):Array.isArray(e)&&(e=new a.Array(e)),"leading"==t?this.leading&&this.leading(e):"string"==typeof i?this.node.setAttributeNS(i,t,e.toString()):this.node.setAttribute(t,e.toString()),!this.rebuild||"font-size"!=t&&"x"!=t||this.rebuild(t,e)}return this},transform:function(t,e){if(0==arguments.length)return this.trans;if("string"==typeof t){if(arguments.length<2)return this.trans[t];var i={};return i[t]=e,this.transform(i)}var i=[];t=o(t);for(e in t)null!=t[e]&&(this.trans[e]=t[e]);return this.trans.matrix=this.trans.a+" "+this.trans.b+" "+this.trans.c+" "+this.trans.d+" "+this.trans.e+" "+this.trans.f,t=this.trans,t.matrix!=a.defaults.matrix&&i.push("matrix("+t.matrix+")"),0!=t.rotation&&i.push("rotate("+t.rotation+" "+(null==t.cx?this.bbox().cx:t.cx)+" "+(null==t.cy?this.bbox().cy:t.cy)+")"),(1!=t.scaleX||1!=t.scaleY)&&i.push("scale("+t.scaleX+" "+t.scaleY+")"),0!=t.skewX&&i.push("skewX("+t.skewX+")"),0!=t.skewY&&i.push("skewY("+t.skewY+")"),(0!=t.x||0!=t.y)&&i.push("translate("+new a.Number(t.x/t.scaleX)+" "+new a.Number(t.y/t.scaleY)+")"),0==i.length?this.node.removeAttribute("transform"):this.node.setAttribute("transform",i.join(" ")),this},style:function(e,i){if(0==arguments.length)return this.node.style.cssText||"";if(arguments.length<2)if("object"==typeof e)for(i in e)this.style(i,e[i]);else{if(!a.regex.isCss.test(e))return this.node.style[t(e)];e=e.split(";");for(var n=0;n<e.length;n++)i=e[n].split(":"),this.style(i[0].replace(/\s+/g,""),i[1])}else this.node.style[t(e)]=null===i||a.regex.isBlank.test(i)?"":i;return this},bbox:function(){return new a.BBox(this)},rbox:function(){return new a.RBox(this)},inside:function(t,e){var i=this.bbox();return t>i.x&&e>i.y&&t<i.x+i.width&&e<i.y+i.height},show:function(){return this.style("display","")},hide:function(){return this.style("display","none")},visible:function(){return"none"!=this.style("display")},toString:function(){return this.attr("id")},classes:function(){var t=this.node.getAttribute("class");return null===t?[]:t.trim().split(/\s+/)},hasClass:function(t){return-1!=this.classes().indexOf(t)},addClass:function(t){var e;return this.hasClass(t)||(e=this.classes(),e.push(t),this.node.setAttribute("class",e.join(" "))),this},removeClass:function(t){var e;return this.hasClass(t)&&(e=this.classes().filter(function(e){return e!=t}),this.node.setAttribute("class",e.join(" "))),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t),this},_parent:function(t){for(var e=this;null!=e&&!(e instanceof t);)e=e.parent;return e}}}),a.Parent=a.invent({create:function(t){this.constructor.call(this,t)},inherit:a.Element,extend:{children:function(){return this._children||(this._children=[])},add:function(t,e){return this.has(t)||(e=null==e?this.children().length:e,t.parent&&t.parent.children().splice(t.parent.index(t),1),this.children().splice(e,0,t),this.node.insertBefore(t.node,this.node.childNodes[e]||null),t.parent=this),this._defs&&(this.node.removeChild(this._defs.node),this.node.appendChild(this._defs.node)),this},put:function(t,e){return this.add(t,e),t},has:function(t){return this.index(t)>=0},index:function(t){return this.children().indexOf(t)},get:function(t){return this.children()[t]},first:function(){return this.children()[0]},last:function(){return this.children()[this.children().length-1]},each:function(t,e){var i,n,r=this.children();for(i=0,n=r.length;n>i;i++)r[i]instanceof a.Element&&t.apply(r[i],[i,r]),e&&r[i]instanceof a.Container&&r[i].each(t,e);return this},removeElement:function(t){return this.children().splice(this.index(t),1),this.node.removeChild(t.node),t.parent=null,this},clear:function(){for(var t=this.children().length-1;t>=0;t--)this.removeElement(this.children()[t]);return this._defs&&this._defs.clear(),this},defs:function(){return this.doc().defs()}}}),a.Container=a.invent({create:function(t){this.constructor.call(this,t)},inherit:a.Parent,extend:{viewbox:function(t){return 0==arguments.length?new a.ViewBox(this):(t=1==arguments.length?[t.x,t.y,t.width,t.height]:[].slice.call(arguments),this.attr("viewBox",t))}}}),a.FX=a.invent({create:function(t){this.target=t},extend:{animate:function(t,e,i){var n,s,h,o,u=this.target,l=this;return"object"==typeof t&&(i=t.delay,e=t.ease,t=t.duration),t="="==t?t:null==t?1e3:new a.Number(t).valueOf(),e=e||"<>",l.to=function(t){var i;if(t=0>t?0:t>1?1:t,null==n){n=[];for(o in l.attrs)n.push(o);if(u.morphArray&&(l._plot||n.indexOf("points")>-1)){var a,c=new u.morphArray(l._plot||l.attrs.points||u.array);l._size&&c.size(l._size.width.to,l._size.height.to),a=c.bbox(),l._x?c.move(l._x.to,a.y):l._cx&&c.move(l._cx.to-a.width/2,a.y),a=c.bbox(),l._y?c.move(a.x,l._y.to):l._cy&&c.move(a.x,l._cy.to-a.height/2),delete l._x,delete l._y,delete l._cx,delete l._cy,delete l._size,l._plot=u.array.morph(c)}}if(null==s){s=[];for(o in l.trans)s.push(o)}if(null==h){h=[];for(o in l.styles)h.push(o)}for(t="<>"==e?-Math.cos(t*Math.PI)/2+.5:">"==e?Math.sin(t*Math.PI/2):"<"==e?-Math.cos(t*Math.PI/2)+1:"-"==e?t:"function"==typeof e?e(t):t,l._plot?u.plot(l._plot.at(t)):(l._x?u.x(l._x.at(t)):l._cx&&u.cx(l._cx.at(t)),l._y?u.y(l._y.at(t)):l._cy&&u.cy(l._cy.at(t)),l._size&&u.size(l._size.width.at(t),l._size.height.at(t))),l._viewbox&&u.viewbox(l._viewbox.x.at(t),l._viewbox.y.at(t),l._viewbox.width.at(t),l._viewbox.height.at(t)),l._leading&&u.leading(l._leading.at(t)),i=n.length-1;i>=0;i--)u.attr(n[i],r(l.attrs[n[i]],t));for(i=s.length-1;i>=0;i--)u.transform(s[i],r(l.trans[s[i]],t));for(i=h.length-1;i>=0;i--)u.style(h[i],r(l.styles[h[i]],t));l._during&&l._during.call(u,t,function(e,i){return r({from:e,to:i},t)})},"number"==typeof t&&(this.timeout=setTimeout(function(){var n=(new Date).getTime();l.situation={interval:1e3/60,start:n,play:!0,finish:n+t,duration:t},l.render=function(){if(l.situation.play===!0){var n=(new Date).getTime(),r=n>l.situation.finish?1:(n-l.situation.start)/t;l.to(r),n>l.situation.finish?(l._plot&&u.plot(new a.PointArray(l._plot.destination).settle()),l._loop===!0||"number"==typeof l._loop&&l._loop>1?("number"==typeof l._loop&&--l._loop,l.animate(t,e,i)):l._after?l._after.apply(u,[l]):l.stop()):requestAnimFrame(l.render)}else requestAnimFrame(l.render)},l.render()},new a.Number(i).valueOf())),this},bbox:function(){return this.target.bbox()},attr:function(t,e){if("object"==typeof t)for(var i in t)this.attr(i,t[i]);else{var n=this.target.attr(t);this.attrs[t]=a.Color.isColor(n)?new a.Color(n).morph(e):a.regex.unit.test(n)?new a.Number(n).morph(e):{from:n,to:e}}return this},transform:function(t,e){if(1==arguments.length){t=o(t),delete t.matrix;for(e in t)this.trans[e]={from:this.target.trans[e],to:t[e]}}else{var i={};i[t]=e,this.transform(i)}return this},style:function(t,e){if("object"==typeof t)for(var i in t)this.style(i,t[i]);else this.styles[t]={from:this.target.style(t),to:e};return this},x:function(t){return this._x=new a.Number(this.target.x()).morph(t),this},y:function(t){return this._y=new a.Number(this.target.y()).morph(t),this},cx:function(t){return this._cx=new a.Number(this.target.cx()).morph(t),this},cy:function(t){return this._cy=new a.Number(this.target.cy()).morph(t),this},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},size:function(t,e){if(this.target instanceof a.Text)this.attr("font-size",t);else{var i=this.target.bbox();this._size={width:new a.Number(i.width).morph(t),height:new a.Number(i.height).morph(e)}}return this},plot:function(t){return this._plot=t,this},leading:function(t){return this.target._leading&&(this._leading=new a.Number(this.target._leading).morph(t)),this},viewbox:function(t,e,i,n){if(this.target instanceof a.Container){var r=this.target.viewbox();this._viewbox={x:new a.Number(r.x).morph(t),y:new a.Number(r.y).morph(e),width:new a.Number(r.width).morph(i),height:new a.Number(r.height).morph(n)}}return this},update:function(t){return this.target instanceof a.Stop&&(null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new a.Number(t.offset))),this},during:function(t){return this._during=t,this},after:function(t){return this._after=t,this},loop:function(t){return this._loop=t||!0,this},stop:function(t){return t===!0?(this.animate(0),this._after&&this._after.apply(this.target,[this])):(clearTimeout(this.timeout),this.attrs={},this.trans={},this.styles={},this.situation={},delete this._x,delete this._y,delete this._cx,delete this._cy,delete this._size,delete this._plot,delete this._loop,delete this._after,delete this._during,delete this._leading,delete this._viewbox),this},pause:function(){return this.situation.play===!0&&(this.situation.play=!1,this.situation.pause=(new Date).getTime()),this},play:function(){if(this.situation.play===!1){var t=(new Date).getTime()-this.situation.pause;this.situation.finish+=t,this.situation.start+=t,this.situation.play=!0}return this}},parent:a.Element,construct:{animate:function(t,e,i){return(this.fx||(this.fx=new a.FX(this))).stop().animate(t,e,i)},stop:function(t){return this.fx&&this.fx.stop(t),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this}}}),a.extend(a.Element,a.FX,{dx:function(t){return this.x((this.target||this).x()+t)},dy:function(t){return this.y((this.target||this).y()+t)},dmove:function(t,e){return this.dx(t).dy(e)}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach(function(t){a.Element.prototype[t]=function(e){var i=this;return this.node["on"+t]="function"==typeof e?function(){return e.apply(i,arguments)}:null,this}}),a.events={},a.listeners={},a.registerEvent=function(t){a.events[t]||(a.events[t]=new Event(t))},a.on=function(t,e,i){var n=i.bind(t.instance||t);a.listeners[i]=n,t.addEventListener(e,n,!1)},a.off=function(t,e,i){t.removeEventListener(e,a.listeners[i],!1),delete a.listeners[i]},a.extend(a.Element,{on:function(t,e){return a.on(this.node,t,e),this},off:function(t,e){return a.off(this.node,t,e),this},fire:function(t){return this.node.dispatchEvent(a.events[t]),this}}),a.Defs=a.invent({create:"defs",inherit:a.Container}),a.G=a.invent({create:"g",inherit:a.Container,extend:{x:function(t){return null==t?this.trans.x:this.transform("x",t)},y:function(t){return null==t?this.trans.y:this.transform("y",t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)}},construct:{group:function(){return this.put(new a.G)}}}),a.extend(a.Element,{siblings:function(){return this.parent.children()},position:function(){return this.parent.index(this)},next:function(){return this.siblings()[this.position()+1]},previous:function(){return this.siblings()[this.position()-1]},forward:function(){var t=this.position();return this.parent.removeElement(this).put(this,t+1)},backward:function(){var t=this.position();return t>0&&this.parent.removeElement(this).add(this,t-1),this},front:function(){return this.parent.removeElement(this).put(this)},back:function(){return this.position()>0&&this.parent.removeElement(this).add(this,0),this},before:function(t){t.remove();var e=this.position();return this.parent.add(t,e),this},after:function(t){t.remove();var e=this.position();return this.parent.add(t,e+1),this}}),a.Mask=a.invent({create:function(){this.constructor.call(this,a.create("mask")),this.targets=[]},inherit:a.Container,extend:{remove:function(){for(var t=this.targets.length-1;t>=0;t--)this.targets[t]&&this.targets[t].unmask();return delete this.targets,this.parent.removeElement(this),this}},construct:{mask:function(){return this.defs().put(new a.Mask)}}}),a.extend(a.Element,{maskWith:function(t){return this.masker=t instanceof a.Mask?t:this.parent.mask().add(t),this.masker.targets.push(this),this.attr("mask",'url("#'+this.masker.attr("id")+'")')},unmask:function(){return delete this.masker,this.attr("mask",null)}}),a.Clip=a.invent({create:function(){this.constructor.call(this,a.create("clipPath")),this.targets=[]},inherit:a.Container,extend:{remove:function(){for(var t=this.targets.length-1;t>=0;t--)this.targets[t]&&this.targets[t].unclip();return delete this.targets,this.parent.removeElement(this),this}},construct:{clip:function(){return this.defs().put(new a.Clip)}}}),a.extend(a.Element,{clipWith:function(t){return this.clipper=t instanceof a.Clip?t:this.parent.clip().add(t),this.clipper.targets.push(this),this.attr("clip-path",'url("#'+this.clipper.attr("id")+'")')},unclip:function(){return delete this.clipper,this.attr("clip-path",null)}}),a.Gradient=a.invent({create:function(t){this.constructor.call(this,a.create(t+"Gradient")),this.type=t},inherit:a.Container,extend:{from:function(t,e){return"radial"==this.type?this.attr({fx:new a.Number(t),fy:new a.Number(e)}):this.attr({x1:new a.Number(t),y1:new a.Number(e)})},to:function(t,e){return"radial"==this.type?this.attr({cx:new a.Number(t),cy:new a.Number(e)}):this.attr({x2:new a.Number(t),y2:new a.Number(e)})},radius:function(t){return"radial"==this.type?this.attr({r:new a.Number(t)}):this},at:function(t,e,i){return this.put(new a.Stop).update(t,e,i)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},fill:function(){return"url(#"+this.attr("id")+")"},toString:function(){return this.fill()}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),a.extend(a.Defs,{gradient:function(t,e){return this.put(new a.Gradient(t)).update(e)}}),a.Stop=a.invent({create:"stop",inherit:a.Element,extend:{update:function(t){return("number"==typeof t||t instanceof a.Number)&&(t={offset:arguments[0],color:arguments[1],opacity:arguments[2]}),null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new a.Number(t.offset)),this}}}),a.Pattern=a.invent({create:"pattern",inherit:a.Container,extend:{fill:function(){return"url(#"+this.attr("id")+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.fill()}},construct:{pattern:function(t,e,i){return this.defs().pattern(t,e,i)}}}),a.extend(a.Defs,{pattern:function(t,e,i){return this.put(new a.Pattern).update(i).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),a.Doc=a.invent({create:function(t){this.parent="string"==typeof t?document.getElementById(t):t,this.constructor.call(this,"svg"==this.parent.nodeName?this.parent:a.create("svg")),this.attr({xmlns:a.ns,version:"1.1",width:"100%",height:"100%"}).attr("xmlns:xlink",a.xlink,a.xmlns),this._defs=new a.Defs,this._defs.parent=this,this.node.appendChild(this._defs.node),this.doSpof=!1,this.parent!=this.node&&this.stage()},inherit:a.Container,extend:{stage:function(){var t=this;return this.parent.appendChild(this.node),t.spof(),a.on(window,"resize",function(){t.spof()}),this},defs:function(){return this._defs},spof:function(){if(this.doSpof){var t=this.node.getScreenCTM();t&&this.style("left",-t.e%1+"px").style("top",-t.f%1+"px")}return this},fixSubPixelOffset:function(){return this.doSpof=!0,this}}}),a.Shape=a.invent({create:function(t){this.constructor.call(this,t)},inherit:a.Element}),a.Use=a.invent({create:"use",inherit:a.Shape,extend:{element:function(t){return this.target=t,this.attr("href","#"+t,a.xlink)}},construct:{use:function(t){return this.put(new a.Use).element(t)}}}),a.Rect=a.invent({create:"rect",inherit:a.Shape,construct:{rect:function(t,e){return this.put((new a.Rect).size(t,e))}}}),a.Ellipse=a.invent({create:"ellipse",inherit:a.Shape,extend:{x:function(t){return null==t?this.cx()-this.attr("rx"):this.cx(t+this.attr("rx"))},y:function(t){return null==t?this.cy()-this.attr("ry"):this.cy(t+this.attr("ry"))},cx:function(t){return null==t?this.attr("cx"):this.attr("cx",new a.Number(t).divide(this.trans.scaleX))},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",new a.Number(t).divide(this.trans.scaleY))},width:function(t){return null==t?2*this.attr("rx"):this.attr("rx",new a.Number(t).divide(2))},height:function(t){return null==t?2*this.attr("ry"):this.attr("ry",new a.Number(t).divide(2))},size:function(t,e){var i=n(this.bbox(),t,e);return this.attr({rx:new a.Number(i.width).divide(2),ry:new a.Number(i.height).divide(2)})}},construct:{circle:function(t){return this.ellipse(t,t)},ellipse:function(t,e){return this.put(new a.Ellipse).size(t,e).move(0,0)}}}),a.Line=a.invent({create:"line",inherit:a.Shape,extend:{x:function(t){var e=this.bbox();return null==t?e.x:this.attr({x1:this.attr("x1")-e.x+t,x2:this.attr("x2")-e.x+t})},y:function(t){var e=this.bbox();return null==t?e.y:this.attr({y1:this.attr("y1")-e.y+t,y2:this.attr("y2")-e.y+t})},cx:function(t){var e=this.bbox().width/2;return null==t?this.x()+e:this.x(t-e)},cy:function(t){var e=this.bbox().height/2;return null==t?this.y()+e:this.y(t-e)},width:function(t){var e=this.bbox();return null==t?e.width:this.attr(this.attr("x1")<this.attr("x2")?"x2":"x1",e.x+t)},height:function(t){var e=this.bbox();return null==t?e.height:this.attr(this.attr("y1")<this.attr("y2")?"y2":"y1",e.y+t)},size:function(t,e){var i=n(this.bbox(),t,e);return this.width(i.width).height(i.height)},plot:function(t,e,i,n){return this.attr({x1:t,y1:e,x2:i,y2:n})}},construct:{line:function(t,e,i,n){return this.put((new a.Line).plot(t,e,i,n))}}}),a.Polyline=a.invent({create:"polyline",inherit:a.Shape,construct:{polyline:function(t){return this.put(new a.Polyline).plot(t)
-}}}),a.Polygon=a.invent({create:"polygon",inherit:a.Shape,construct:{polygon:function(t){return this.put(new a.Polygon).plot(t)}}}),a.extend(a.Polyline,a.Polygon,{morphArray:a.PointArray,plot:function(t){return this.attr("points",this.array=new a.PointArray(t,[[0,0]]))},move:function(t,e){return this.attr("points",this.array.move(t,e))},x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},width:function(t){var e=this.bbox();return null==t?e.width:this.size(t,e.height)},height:function(t){var e=this.bbox();return null==t?e.height:this.size(e.width,t)},size:function(t,e){var i=n(this.bbox(),t,e);return this.attr("points",this.array.size(i.width,i.height))}}),a.Path=a.invent({create:"path",inherit:a.Shape,extend:{plot:function(t){return this.attr("d",this.array=new a.PathArray(t,[["M",0,0]]))},move:function(t,e){return this.attr("d",this.array.move(t,e))},x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},size:function(t,e){var i=n(this.bbox(),t,e);return this.attr("d",this.array.size(i.width,i.height))},width:function(t){return null==t?this.bbox().width:this.size(t,this.bbox().height)},height:function(t){return null==t?this.bbox().height:this.size(this.bbox().width,t)}},construct:{path:function(t){return this.put(new a.Path).plot(t)}}}),a.Image=a.invent({create:"image",inherit:a.Shape,extend:{load:function(t){if(!t)return this;var e=this,i=document.createElement("img");return i.onload=function(){var n=e.doc(a.Pattern);0==e.width()&&0==e.height()&&e.size(i.width,i.height),n&&0==n.width()&&0==n.height()&&n.size(e.width(),e.height()),"function"==typeof e._loaded&&e._loaded.call(e,{width:i.width,height:i.height,ratio:i.width/i.height,url:t})},this.attr("href",i.src=this.src=t,a.xlink)},loaded:function(t){return this._loaded=t,this}},construct:{image:function(t,e,i){return this.put(new a.Image).load(t).size(e||0,i||e||0)}}}),a.Text=a.invent({create:function(){this.constructor.call(this,a.create("text")),this._leading=new a.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",a.defaults.attrs["font-family"])},inherit:a.Shape,extend:{x:function(t){return null==t?this.attr("x"):(this.textPath||this.lines.each(function(){this.newLined&&this.x(t)}),this.attr("x",t))},y:function(t){var e=this.attr("y"),i="number"==typeof e?e-this.bbox().y:0;return null==t?"number"==typeof e?e-i:e:this.attr("y","number"==typeof t?t+i:t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)},text:function(t){if("undefined"==typeof t)return this.content;if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{t=(this.content=t).split("\n");for(var e=0,i=t.length;i>e;e++)this.tspan(t[e]).newLine()}return this.build(!1).rebuild()},size:function(t){return this.attr("font-size",t).rebuild()},leading:function(t){return null==t?this._leading:(this._leading=new a.Number(t),this.rebuild())},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this;this.lines.each(function(){this.newLined&&(this.textPath||this.attr("x",e.attr("x")),this.attr("dy",e._leading*new a.Number(e.attr("font-size"))))}),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this}},construct:{text:function(t){return this.put(new a.Text).text(t)},plain:function(t){return this.put(new a.Text).plain(t)}}}),a.TSpan=a.invent({create:"tspan",inherit:a.Shape,extend:{text:function(t){return"function"==typeof t?t.call(this,this):this.plain(t),this},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.doc(a.Text);return this.newLined=!0,this.dy(t._leading*t.attr("font-size")).attr("x",t.x())}}}),a.extend(a.Text,a.TSpan,{plain:function(t){return this._build===!1&&this.clear(),this.node.appendChild(document.createTextNode(this.content=t)),this},tspan:function(t){var e=(this.textPath||this).node,i=new a.TSpan;return this._build===!1&&this.clear(),e.appendChild(i.node),i.parent=this,this instanceof a.Text&&this.lines.add(i),i.text(t)},clear:function(){for(var t=(this.textPath||this).node;t.hasChildNodes();)t.removeChild(t.lastChild);return this instanceof a.Text&&(delete this.lines,this.lines=new a.Set,this.content=""),this}}),a.registerEvent("rebuild"),a.TextPath=a.invent({create:"textPath",inherit:a.Element,parent:a.Text,construct:{path:function(t){for(this.textPath=new a.TextPath;this.node.hasChildNodes();)this.textPath.node.appendChild(this.node.firstChild);return this.node.appendChild(this.textPath.node),this.track=this.doc().defs().path(t),this.textPath.parent=this,this.textPath.attr("href","#"+this.track,a.xlink),this},plot:function(t){return this.track&&this.track.plot(t),this}}}),a.Nested=a.invent({create:function(){this.constructor.call(this,a.create("svg")),this.style("overflow","visible")},inherit:a.Container,construct:{nested:function(){return this.put(new a.Nested)}}}),a.A=a.invent({create:"a",inherit:a.Container,extend:{to:function(t){return this.attr("href",t,a.xlink)},show:function(t){return this.attr("show",t,a.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new a.A).to(t)}}}),a.extend(a.Element,{linkTo:function(t){var e=new a.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent.put(e).put(this)}});var u={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(t,e){return"color"==e?t:t+"-"+e}};["fill","stroke"].forEach(function(t){var e,i={};i[t]=function(i){if("string"==typeof i||a.Color.isRgb(i)||i&&"function"==typeof i.fill)this.attr(t,i);else for(e=u[t].length-1;e>=0;e--)null!=i[u[t][e]]&&this.attr(u.prefix(t,u[t][e]),i[u[t][e]]);return this},a.extend(a.Element,a.FX,i)}),a.extend(a.Element,a.FX,{rotate:function(t,e,i){return this.transform({rotation:t||0,cx:e,cy:i})},skew:function(t,e){return this.transform({skewX:t||0,skewY:e||0})},scale:function(t,e){return this.transform({scaleX:t,scaleY:null==e?t:e})},translate:function(t,e){return this.transform({x:t,y:e})},matrix:function(t){return this.transform({matrix:t})},opacity:function(t){return this.attr("opacity",t)}}),a.extend(a.Rect,a.Ellipse,a.FX,{radius:function(t,e){return this.attr({rx:t,ry:e||t})}}),a.extend(a.Path,{length:function(){return this.node.getTotalLength()},pointAt:function(t){return this.node.getPointAtLength(t)}}),a.extend(a.Parent,a.Text,a.FX,{font:function(t){for(var e in t)"leading"==e?this.leading(t[e]):"anchor"==e?this.attr("text-anchor",t[e]):"size"==e||"family"==e||"weight"==e||"stretch"==e||"variant"==e||"style"==e?this.attr("font-"+e,t[e]):this.attr(e,t[e]);return this}}),a.Set=a.invent({create:function(){this.clear()},extend:{add:function(){var t,e,i=[].slice.call(arguments);for(t=0,e=i.length;e>t;t++)this.members.push(i[t]);return this},remove:function(t){var e=this.index(t);return e>-1&&this.members.splice(e,1),this},each:function(t){for(var e=0,i=this.members.length;i>e;e++)t.apply(this.members[e],[e,this.members]);return this},clear:function(){return this.members=[],this},has:function(t){return this.index(t)>=0},index:function(t){return this.members.indexOf(t)},get:function(t){return this.members[t]},valueOf:function(){return this.members},bbox:function(){var t=new a.BBox;if(0==this.members.length)return t;var e=this.members[0].rbox();return t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,this.each(function(){t=t.merge(this.rbox())}),t}},construct:{set:function(){return new a.Set}}}),a.SetFX=a.invent({create:function(t){this.set=t}}),a.Set.inherit=function(){var t,e=[];for(var t in a.Shape.prototype)"function"==typeof a.Shape.prototype[t]&&"function"!=typeof a.Set.prototype[t]&&e.push(t);e.forEach(function(t){a.Set.prototype[t]=function(){for(var e=0,i=this.members.length;i>e;e++)this.members[e]&&"function"==typeof this.members[e][t]&&this.members[e][t].apply(this.members[e],arguments);return"animate"==t?this.fx||(this.fx=new a.SetFX(this)):this}}),e=[];for(var t in a.FX.prototype)"function"==typeof a.FX.prototype[t]&&"function"!=typeof a.SetFX.prototype[t]&&e.push(t);e.forEach(function(t){a.SetFX.prototype[t]=function(){for(var e=0,i=this.set.members.length;i>e;e++)this.set.members[e].fx[t].apply(this.set.members[e].fx,arguments);return this}})},a.extend(a.Element,{data:function(t,e,i){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+t))}catch(n){return this.attr("data-"+t)}else this.attr("data-"+t,null===e?null:i===!0||"string"==typeof e||"number"==typeof e?e:JSON.stringify(e));return this}}),a.extend(a.Element,{remember:function(t,e){if("object"==typeof arguments[0])for(var e in t)this.remember(e,t[e]);else{if(1==arguments.length)return this.memory()[t];this.memory()[t]=e}return this},forget:function(){if(0==arguments.length)this._memory={};else for(var t=arguments.length-1;t>=0;t--)delete this.memory()[arguments[t]];return this},memory:function(){return this._memory||(this._memory={})}}),"function"==typeof define&&define.amd?define(function(){return a}):"undefined"!=typeof exports&&(exports.SVG=a),window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)}}()}).call(this);
\ No newline at end of file
+(function(){function t(t){return t.toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()})}function e(t){return 4==t.length?["#",t.substring(1,2),t.substring(1,2),t.substring(2,3),t.substring(2,3),t.substring(3,4),t.substring(3,4)].join(""):t}function i(t){var e=t.toString(16);return 1==e.length?"0"+e:e}function n(t,e,i){return(null==e||null==i)&&(null==i?i=t.height/t.width*e:null==e&&(e=t.width/t.height*i)),{width:e,height:i}}function r(t,e){return"number"==typeof t.from?t.from+(t.to-t.from)*e:t instanceof u.Color||t instanceof u.Number?t.at(e):1>e?t.from:t.to}function s(t){for(var e=0,i=t.length,n="";i>e;e++)n+=t[e][0],null!=t[e][1]&&(n+=t[e][1],null!=t[e][2]&&(n+=" ",n+=t[e][2],null!=t[e][3]&&(n+=" ",n+=t[e][3],n+=" ",n+=t[e][4],null!=t[e][5]&&(n+=" ",n+=t[e][5],n+=" ",n+=t[e][6],null!=t[e][7]&&(n+=" ",n+=t[e][7])))));return n+" "}function h(t){t.x2=t.x+t.width,t.y2=t.y+t.height,t.cx=t.x+t.width/2,t.cy=t.y+t.height/2}function o(t){if(t.matrix){var e=t.matrix.replace(/\s/g,"").split(",");6==e.length&&(t.a=parseFloat(e[0]),t.b=parseFloat(e[1]),t.c=parseFloat(e[2]),t.d=parseFloat(e[3]),t.e=parseFloat(e[4]),t.f=parseFloat(e[5]))}return t}function a(t){var e=t.toString().match(u.regex.reference);return e?e[1]:void 0}var u=this.SVG=function(t){return u.supported?(t=new u.Doc(t),u.parser||u.prepare(t),t):void 0};if(u.ns="http://www.w3.org/2000/svg",u.xmlns="http://www.w3.org/2000/xmlns/",u.xlink="http://www.w3.org/1999/xlink",u.did=1e3,u.eid=function(t){return"Svgjs"+t.charAt(0).toUpperCase()+t.slice(1)+u.did++},u.create=function(t){var e=document.createElementNS(this.ns,t);return e.setAttribute("id",this.eid(t)),e},u.extend=function(){var t,e,i,n;for(t=[].slice.call(arguments),e=t.pop(),n=t.length-1;n>=0;n--)if(t[n])for(i in e)t[n].prototype[i]=e[i];u.Set&&u.Set.inherit&&u.Set.inherit()},u.prepare=function(t){var e=document.getElementsByTagName("body")[0],i=(e?new u.Doc(e):t.nested()).size(2,0),n=u.create("path");i.node.appendChild(n),u.parser={body:e||t.parent,draw:i.style("opacity:0;position:fixed;left:100%;top:100%;overflow:hidden"),poly:i.polyline().node,path:n}},u.supported=function(){return!!document.createElementNS&&!!document.createElementNS(u.ns,"svg").createSVGRect}(),!u.supported)return!1;u.get=function(t){var e=document.getElementById(a(t)||t);return e?e.instance:void 0},u.invent=function(t){var e="function"==typeof t.create?t.create:function(){this.constructor.call(this,u.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&u.extend(e,t.extend),t.construct&&u.extend(t.parent||u.Container,t.construct),e},u.regex={unit:/^(-?[\d\.]+)([a-z%]{0,2})$/,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,reference:/#([a-z0-9\-_]+)/i,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^-?[\d\.]+$/,isPercent:/^-?[\d\.]+%$/,isImage:/\.(jpg|jpeg|png|gif)(\?[^=]+.*)?/i,isEvent:/^[\w]+:[\w]+$/},u.defaults={matrix:"1 0 0 1 0 0",attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"},trans:function(){return{x:0,y:0,scaleX:1,scaleY:1,rotation:0,skewX:0,skewY:0,matrix:this.matrix,a:1,b:0,c:0,d:1,e:0,f:0}}},u.Color=function(t){var i;this.r=0,this.g=0,this.b=0,"string"==typeof t?u.regex.isRgb.test(t)?(i=u.regex.rgb.exec(t.replace(/\s/g,"")),this.r=parseInt(i[1]),this.g=parseInt(i[2]),this.b=parseInt(i[3])):u.regex.isHex.test(t)&&(i=u.regex.hex.exec(e(t)),this.r=parseInt(i[1],16),this.g=parseInt(i[2],16),this.b=parseInt(i[3],16)):"object"==typeof t&&(this.r=t.r,this.g=t.g,this.b=t.b)},u.extend(u.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+i(this.r)+i(this.g)+i(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},morph:function(t){return this.destination=new u.Color(t),this},at:function(t){return this.destination?(t=0>t?0:t>1?1:t,new u.Color({r:~~(this.r+(this.destination.r-this.r)*t),g:~~(this.g+(this.destination.g-this.g)*t),b:~~(this.b+(this.destination.b-this.b)*t)})):this}}),u.Color.test=function(t){return t+="",u.regex.isHex.test(t)||u.regex.isRgb.test(t)},u.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},u.Color.isColor=function(t){return u.Color.isRgb(t)||u.Color.test(t)},u.Array=function(t,e){t=(t||[]).valueOf(),0==t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},u.extend(u.Array,{morph:function(t){if(this.destination=this.parse(t),this.value.length!=this.destination.length){for(var e=this.value[this.value.length-1],i=this.destination[this.destination.length-1];this.value.length>this.destination.length;)this.destination.push(i);for(;this.value.length<this.destination.length;)this.value.push(e)}return this},settle:function(){for(var t=0,e=this.value.length,i=[];e>t;t++)-1==i.indexOf(this.value[t])&&i.push(this.value[t]);return this.value=i},at:function(t){if(!this.destination)return this;for(var e=0,i=this.value.length,n=[];i>e;e++)n.push(this.value[e]+(this.destination[e]-this.value[e])*t);return new u.Array(n)},toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:this.split(t)},split:function(t){return t.replace(/\s+/g," ").replace(/^\s+|\s+$/g,"").split(" ")},reverse:function(){return this.value.reverse(),this}}),u.PointArray=function(){this.constructor.apply(this,arguments)},u.PointArray.prototype=new u.Array,u.extend(u.PointArray,{toString:function(){for(var t=0,e=this.value.length,i=[];e>t;t++)i.push(this.value[t].join(","));return i.join(" ")},at:function(t){if(!this.destination)return this;for(var e=0,i=this.value.length,n=[];i>e;e++)n.push([this.value[e][0]+(this.destination[e][0]-this.value[e][0])*t,this.value[e][1]+(this.destination[e][1]-this.value[e][1])*t]);return new u.PointArray(n)},parse:function(t){if(t=t.valueOf(),Array.isArray(t))return t;t=this.split(t);for(var e,i=0,n=t.length,r=[];n>i;i++)e=t[i].split(","),r.push([parseFloat(e[0]),parseFloat(e[1])]);return r},move:function(t,e){var i=this.bbox();if(t-=i.x,e-=i.y,!isNaN(t)&&!isNaN(e))for(var n=this.value.length-1;n>=0;n--)this.value[n]=[this.value[n][0]+t,this.value[n][1]+e];return this},size:function(t,e){var i,n=this.bbox();for(i=this.value.length-1;i>=0;i--)this.value[i][0]=(this.value[i][0]-n.x)*t/n.width+n.x,this.value[i][1]=(this.value[i][1]-n.y)*e/n.height+n.y;return this},bbox:function(){return u.parser.poly.setAttribute("points",this.toString()),u.parser.poly.getBBox()}}),u.PathArray=function(t,e){this.constructor.call(this,t,e)},u.PathArray.prototype=new u.Array,u.extend(u.PathArray,{toString:function(){return s(this.value)},move:function(t,e){var i=this.bbox();if(t-=i.x,e-=i.y,!isNaN(t)&&!isNaN(e))for(var n,r=this.value.length-1;r>=0;r--)n=this.value[r][0],"M"==n||"L"==n||"T"==n?(this.value[r][1]+=t,this.value[r][2]+=e):"H"==n?this.value[r][1]+=t:"V"==n?this.value[r][1]+=e:"C"==n||"S"==n||"Q"==n?(this.value[r][1]+=t,this.value[r][2]+=e,this.value[r][3]+=t,this.value[r][4]+=e,"C"==n&&(this.value[r][5]+=t,this.value[r][6]+=e)):"A"==n&&(this.value[r][6]+=t,this.value[r][7]+=e);return this},size:function(t,e){var i,n,r=this.bbox();for(i=this.value.length-1;i>=0;i--)n=this.value[i][0],"M"==n||"L"==n||"T"==n?(this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x,this.value[i][2]=(this.value[i][2]-r.y)*e/r.height+r.y):"H"==n?this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x:"V"==n?this.value[i][1]=(this.value[i][1]-r.y)*e/r.height+r.y:"C"==n||"S"==n||"Q"==n?(this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x,this.value[i][2]=(this.value[i][2]-r.y)*e/r.height+r.y,this.value[i][3]=(this.value[i][3]-r.x)*t/r.width+r.x,this.value[i][4]=(this.value[i][4]-r.y)*e/r.height+r.y,"C"==n&&(this.value[i][5]=(this.value[i][5]-r.x)*t/r.width+r.x,this.value[i][6]=(this.value[i][6]-r.y)*e/r.height+r.y)):"A"==n&&(this.value[i][1]=this.value[i][1]*t/r.width,this.value[i][2]=this.value[i][2]*e/r.height,this.value[i][6]=(this.value[i][6]-r.x)*t/r.width+r.x,this.value[i][7]=(this.value[i][7]-r.y)*e/r.height+r.y);return this},parse:function(t){if(t instanceof u.PathArray)return t.valueOf();var e,i,n,r,h,o,a,l,c,f,d,p=0,x=0;for(u.parser.path.setAttribute("d","string"==typeof t?t:s(t)),d=u.parser.path.pathSegList,e=0,i=d.numberOfItems;i>e;++e)f=d.getItem(e),c=f.pathSegTypeAsLetter,"M"==c||"L"==c||"H"==c||"V"==c||"C"==c||"S"==c||"Q"==c||"T"==c||"A"==c?("x"in f&&(p=f.x),"y"in f&&(x=f.y)):("x1"in f&&(h=p+f.x1),"x2"in f&&(a=p+f.x2),"y1"in f&&(o=x+f.y1),"y2"in f&&(l=x+f.y2),"x"in f&&(p+=f.x),"y"in f&&(x+=f.y),"m"==c?d.replaceItem(u.parser.path.createSVGPathSegMovetoAbs(p,x),e):"l"==c?d.replaceItem(u.parser.path.createSVGPathSegLinetoAbs(p,x),e):"h"==c?d.replaceItem(u.parser.path.createSVGPathSegLinetoHorizontalAbs(p),e):"v"==c?d.replaceItem(u.parser.path.createSVGPathSegLinetoVerticalAbs(x),e):"c"==c?d.replaceItem(u.parser.path.createSVGPathSegCurvetoCubicAbs(p,x,h,o,a,l),e):"s"==c?d.replaceItem(u.parser.path.createSVGPathSegCurvetoCubicSmoothAbs(p,x,a,l),e):"q"==c?d.replaceItem(u.parser.path.createSVGPathSegCurvetoQuadraticAbs(p,x,h,o),e):"t"==c?d.replaceItem(u.parser.path.createSVGPathSegCurvetoQuadraticSmoothAbs(p,x),e):"a"==c?d.replaceItem(u.parser.path.createSVGPathSegArcAbs(p,x,f.r1,f.r2,f.angle,f.largeArcFlag,f.sweepFlag),e):("z"==c||"Z"==c)&&(p=n,x=r)),("M"==c||"m"==c)&&(n=p,r=x);for(t=[],d=u.parser.path.pathSegList,e=0,i=d.numberOfItems;i>e;++e)f=d.getItem(e),c=f.pathSegTypeAsLetter,p=[c],"M"==c||"L"==c||"T"==c?p.push(f.x,f.y):"H"==c?p.push(f.x):"V"==c?p.push(f.y):"C"==c?p.push(f.x1,f.y1,f.x2,f.y2,f.x,f.y):"S"==c?p.push(f.x2,f.y2,f.x,f.y):"Q"==c?p.push(f.x1,f.y1,f.x,f.y):"A"==c&&p.push(f.r1,f.r2,f.angle,0|f.largeArcFlag,0|f.sweepFlag,f.x,f.y),t.push(p);return t},bbox:function(){return u.parser.path.setAttribute("d",this.toString()),u.parser.path.getBBox()}}),u.Number=function(t){if(this.value=0,this.unit="","number"==typeof t)this.value=isNaN(t)?0:isFinite(t)?t:0>t?-3.4e38:3.4e38;else if("string"==typeof t){var e=t.match(u.regex.unit);e&&(this.value=parseFloat(e[1]),"%"==e[2]?this.value/=100:"s"==e[2]&&(this.value*=1e3),this.unit=e[2])}else t instanceof u.Number&&(this.value=t.value,this.unit=t.unit)},u.extend(u.Number,{toString:function(){return("%"==this.unit?~~(1e8*this.value)/1e6:"s"==this.unit?this.value/1e3:this.value)+this.unit},valueOf:function(){return this.value},plus:function(t){return this.value=this+new u.Number(t),this},minus:function(t){return this.plus(-new u.Number(t))},times:function(t){return this.value=this*new u.Number(t),this},divide:function(t){return this.value=this/new u.Number(t),this},to:function(t){return"string"==typeof t&&(this.unit=t),this},morph:function(t){return this.destination=new u.Number(t),this},at:function(t){return this.destination?new u.Number(this.destination).minus(this).times(t).plus(this):this}}),u.ViewBox=function(t){var e,i,n,r,s=1,h=1,o=t.bbox(),a=(t.attr("viewBox")||"").match(/-?[\d\.]+/g);for(n=new u.Number(t.width()),r=new u.Number(t.height());"%"==n.unit;)s*=n.value,n=new u.Number(t instanceof u.Doc?t.parent.offsetWidth:t.width());for(;"%"==r.unit;)h*=r.value,r=new u.Number(t instanceof u.Doc?t.parent.offsetHeight:t.height());this.x=o.x,this.y=o.y,this.width=n*s,this.height=r*h,this.zoom=1,a&&(e=parseFloat(a[0]),i=parseFloat(a[1]),n=parseFloat(a[2]),r=parseFloat(a[3]),this.zoom=this.width/this.height>n/r?this.height/r:this.width/n,this.x=e,this.y=i,this.width=n,this.height=r)},u.extend(u.ViewBox,{toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height}}),u.BBox=function(t){var e;if(this.x=0,this.y=0,this.width=0,this.height=0,t){try{e=t.node.getBBox()}catch(i){e={x:t.node.clientLeft,y:t.node.clientTop,width:t.node.clientWidth,height:t.node.clientHeight}}this.x=e.x+t.trans.x,this.y=e.y+t.trans.y,this.width=e.width*t.trans.scaleX,this.height=e.height*t.trans.scaleY}h(this)},u.extend(u.BBox,{merge:function(t){var e=new u.BBox;return e.x=Math.min(this.x,t.x),e.y=Math.min(this.y,t.y),e.width=Math.max(this.x+this.width,t.x+t.width)-e.x,e.height=Math.max(this.y+this.height,t.y+t.height)-e.y,h(e),e}}),u.RBox=function(t){var e,i,n={};if(this.x=0,this.y=0,this.width=0,this.height=0,t){for(e=t.doc().parent,i=t.doc().viewbox().zoom,n=t.node.getBoundingClientRect(),this.x=n.left,this.y=n.top,this.x-=e.offsetLeft,this.y-=e.offsetTop;e=e.offsetParent;)this.x-=e.offsetLeft,this.y-=e.offsetTop;for(e=t;e=e.parent;)"svg"==e.type&&e.viewbox&&(i*=e.viewbox().zoom,this.x-=e.x()||0,this.y-=e.y()||0)}this.x/=i,this.y/=i,this.width=n.width/=i,this.height=n.height/=i,this.x+=window.scrollX,this.y+=window.scrollY,h(this)},u.extend(u.RBox,{merge:function(t){var e=new u.RBox;return e.x=Math.min(this.x,t.x),e.y=Math.min(this.y,t.y),e.width=Math.max(this.x+this.width,t.x+t.width)-e.x,e.height=Math.max(this.y+this.height,t.y+t.height)-e.y,h(e),e}}),u.Element=u.invent({create:function(t){this._stroke=u.defaults.attrs.stroke,this.trans=u.defaults.trans(),(this.node=t)&&(this.type=t.nodeName,this.node.instance=this)},extend:{x:function(t){return null!=t&&(t=new u.Number(t),t.value/=this.trans.scaleX),this.attr("x",t)},y:function(t){return null!=t&&(t=new u.Number(t),t.value/=this.trans.scaleY),this.attr("y",t)},cx:function(t){return null==t?this.x()+this.width()/2:this.x(t-this.width()/2)},cy:function(t){return null==t?this.y()+this.height()/2:this.y(t-this.height()/2)},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},width:function(t){return this.attr("width",t)},height:function(t){return this.attr("height",t)},size:function(t,e){var i=n(this.bbox(),t,e);return this.width(new u.Number(i.width)).height(new u.Number(i.height))},clone:function(){var t,e,i=this.type;return t="rect"==i||"ellipse"==i?this.parent[i](0,0):"line"==i?this.parent[i](0,0,0,0):"image"==i?this.parent[i](this.src):"text"==i?this.parent[i](this.content):"path"==i?this.parent[i](this.attr("d")):"polyline"==i||"polygon"==i?this.parent[i](this.attr("points")):"g"==i?this.parent.group():this.parent[i](),e=this.attr(),delete e.id,t.attr(e),t.trans=this.trans,t.transform({})},remove:function(){return this.parent&&this.parent.removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return t.put(this)},putIn:function(t){return t.add(this)},doc:function(t){return this._parent(t||u.Doc)},attr:function(t,e,i){if(null==t){for(t={},e=this.node.attributes,i=e.length-1;i>=0;i--)t[e[i].nodeName]=u.regex.isNumber.test(e[i].nodeValue)?parseFloat(e[i].nodeValue):e[i].nodeValue;return t}if("object"==typeof t)for(e in t)this.attr(e,t[e]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return e=this.node.getAttribute(t),null==e?u.defaults.attrs[t]:u.regex.isNumber.test(e)?parseFloat(e):e;if("style"==t)return this.style(e);"stroke-width"==t?this.attr("stroke",parseFloat(e)>0?this._stroke:null):"stroke"==t&&(this._stroke=e),("fill"==t||"stroke"==t)&&(u.regex.isImage.test(e)&&(e=this.doc().defs().image(e,0,0)),e instanceof u.Image&&(e=this.doc().defs().pattern(0,0,function(){this.add(e)}))),"number"==typeof e?e=new u.Number(e):u.Color.isColor(e)?e=new u.Color(e):Array.isArray(e)&&(e=new u.Array(e)),"leading"==t?this.leading&&this.leading(e):"string"==typeof i?this.node.setAttributeNS(i,t,e.toString()):this.node.setAttribute(t,e.toString()),!this.rebuild||"font-size"!=t&&"x"!=t||this.rebuild(t,e)}return this},transform:function(t,e){if(0==arguments.length)return this.trans;if("string"==typeof t){if(arguments.length<2)return this.trans[t];var i={};return i[t]=e,this.transform(i)}var i=[];t=o(t);for(e in t)null!=t[e]&&(this.trans[e]=t[e]);return this.trans.matrix=this.trans.a+" "+this.trans.b+" "+this.trans.c+" "+this.trans.d+" "+this.trans.e+" "+this.trans.f,t=this.trans,t.matrix!=u.defaults.matrix&&i.push("matrix("+t.matrix+")"),0!=t.rotation&&i.push("rotate("+t.rotation+" "+(null==t.cx?this.bbox().cx:t.cx)+" "+(null==t.cy?this.bbox().cy:t.cy)+")"),(1!=t.scaleX||1!=t.scaleY)&&i.push("scale("+t.scaleX+" "+t.scaleY+")"),0!=t.skewX&&i.push("skewX("+t.skewX+")"),0!=t.skewY&&i.push("skewY("+t.skewY+")"),(0!=t.x||0!=t.y)&&i.push("translate("+new u.Number(t.x/t.scaleX)+" "+new u.Number(t.y/t.scaleY)+")"),0==i.length?this.node.removeAttribute("transform"):this.node.setAttribute("transform",i.join(" ")),this},style:function(e,i){if(0==arguments.length)return this.node.style.cssText||"";if(arguments.length<2)if("object"==typeof e)for(i in e)this.style(i,e[i]);else{if(!u.regex.isCss.test(e))return this.node.style[t(e)];e=e.split(";");for(var n=0;n<e.length;n++)i=e[n].split(":"),this.style(i[0].replace(/\s+/g,""),i[1])}else this.node.style[t(e)]=null===i||u.regex.isBlank.test(i)?"":i;return this},id:function(t){return this.attr("id",t)},bbox:function(){return new u.BBox(this)},rbox:function(){return new u.RBox(this)},inside:function(t,e){var i=this.bbox();return t>i.x&&e>i.y&&t<i.x+i.width&&e<i.y+i.height},show:function(){return this.style("display","")},hide:function(){return this.style("display","none")},visible:function(){return"none"!=this.style("display")},toString:function(){return this.attr("id")},classes:function(){var t=this.node.getAttribute("class");return null===t?[]:t.trim().split(/\s+/)},hasClass:function(t){return-1!=this.classes().indexOf(t)},addClass:function(t){var e;return this.hasClass(t)||(e=this.classes(),e.push(t),this.node.setAttribute("class",e.join(" "))),this},removeClass:function(t){var e;return this.hasClass(t)&&(e=this.classes().filter(function(e){return e!=t}),this.node.setAttribute("class",e.join(" "))),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t),this},reference:function(t){return u.get(this.attr(t))},_parent:function(t){for(var e=this;null!=e&&!(e instanceof t);)e=e.parent;return e}}}),u.Parent=u.invent({create:function(t){this.constructor.call(this,t)},inherit:u.Element,extend:{children:function(){return this._children||(this._children=[])},add:function(t,e){return this.has(t)||(e=null==e?this.children().length:e,t.parent&&t.parent.children().splice(t.parent.index(t),1),this.children().splice(e,0,t),this.node.insertBefore(t.node,this.node.childNodes[e]||null),t.parent=this),this._defs&&(this.node.removeChild(this._defs.node),this.node.appendChild(this._defs.node)),this},put:function(t,e){return this.add(t,e),t},has:function(t){return this.index(t)>=0},index:function(t){return this.children().indexOf(t)},get:function(t){return this.children()[t]},first:function(){return this.children()[0]},last:function(){return this.children()[this.children().length-1]},each:function(t,e){var i,n,r=this.children();for(i=0,n=r.length;n>i;i++)r[i]instanceof u.Element&&t.apply(r[i],[i,r]),e&&r[i]instanceof u.Container&&r[i].each(t,e);return this},removeElement:function(t){return this.children().splice(this.index(t),1),this.node.removeChild(t.node),t.parent=null,this},clear:function(){for(var t=this.children().length-1;t>=0;t--)this.removeElement(this.children()[t]);return this._defs&&this._defs.clear(),this},defs:function(){return this.doc().defs()}}}),u.Container=u.invent({create:function(t){this.constructor.call(this,t)},inherit:u.Parent,extend:{viewbox:function(t){return 0==arguments.length?new u.ViewBox(this):(t=1==arguments.length?[t.x,t.y,t.width,t.height]:[].slice.call(arguments),this.attr("viewBox",t))}}}),u.FX=u.invent({create:function(t){this.target=t},extend:{animate:function(t,e,i){var n,s,h,o,a=this.target,l=this;return"object"==typeof t&&(i=t.delay,e=t.ease,t=t.duration),t="="==t?t:null==t?1e3:new u.Number(t).valueOf(),e=e||"<>",l.to=function(t){var i;if(t=0>t?0:t>1?1:t,null==n){n=[];for(o in l.attrs)n.push(o);if(a.morphArray&&(l._plot||n.indexOf("points")>-1)){var u,c=new a.morphArray(l._plot||l.attrs.points||a.array);l._size&&c.size(l._size.width.to,l._size.height.to),u=c.bbox(),l._x?c.move(l._x.to,u.y):l._cx&&c.move(l._cx.to-u.width/2,u.y),u=c.bbox(),l._y?c.move(u.x,l._y.to):l._cy&&c.move(u.x,l._cy.to-u.height/2),delete l._x,delete l._y,delete l._cx,delete l._cy,delete l._size,l._plot=a.array.morph(c)}}if(null==s){s=[];for(o in l.trans)s.push(o)}if(null==h){h=[];for(o in l.styles)h.push(o)}for(t="<>"==e?-Math.cos(t*Math.PI)/2+.5:">"==e?Math.sin(t*Math.PI/2):"<"==e?-Math.cos(t*Math.PI/2)+1:"-"==e?t:"function"==typeof e?e(t):t,l._plot?a.plot(l._plot.at(t)):(l._x?a.x(l._x.at(t)):l._cx&&a.cx(l._cx.at(t)),l._y?a.y(l._y.at(t)):l._cy&&a.cy(l._cy.at(t)),l._size&&a.size(l._size.width.at(t),l._size.height.at(t))),l._viewbox&&a.viewbox(l._viewbox.x.at(t),l._viewbox.y.at(t),l._viewbox.width.at(t),l._viewbox.height.at(t)),l._leading&&a.leading(l._leading.at(t)),i=n.length-1;i>=0;i--)a.attr(n[i],r(l.attrs[n[i]],t));for(i=s.length-1;i>=0;i--)a.transform(s[i],r(l.trans[s[i]],t));for(i=h.length-1;i>=0;i--)a.style(h[i],r(l.styles[h[i]],t));l._during&&l._during.call(a,t,function(e,i){return r({from:e,to:i},t)})},"number"==typeof t&&(this.timeout=setTimeout(function(){var n=(new Date).getTime();l.situation={interval:1e3/60,start:n,play:!0,finish:n+t,duration:t},l.render=function(){if(l.situation.play===!0){var n=(new Date).getTime(),r=n>l.situation.finish?1:(n-l.situation.start)/t;l.to(r),n>l.situation.finish?(l._plot&&a.plot(new u.PointArray(l._plot.destination).settle()),l._loop===!0||"number"==typeof l._loop&&l._loop>1?("number"==typeof l._loop&&--l._loop,l.animate(t,e,i)):l._after?l._after.apply(a,[l]):l.stop()):requestAnimFrame(l.render)}else requestAnimFrame(l.render)},l.render()},new u.Number(i).valueOf())),this},bbox:function(){return this.target.bbox()},attr:function(t,e){if("object"==typeof t)for(var i in t)this.attr(i,t[i]);else{var n=this.target.attr(t);this.attrs[t]=u.Color.isColor(n)?new u.Color(n).morph(e):u.regex.unit.test(n)?new u.Number(n).morph(e):{from:n,to:e}}return this},transform:function(t,e){if(1==arguments.length){t=o(t),delete t.matrix;for(e in t)this.trans[e]={from:this.target.trans[e],to:t[e]}}else{var i={};i[t]=e,this.transform(i)}return this},style:function(t,e){if("object"==typeof t)for(var i in t)this.style(i,t[i]);else this.styles[t]={from:this.target.style(t),to:e};return this},x:function(t){return this._x=new u.Number(this.target.x()).morph(t),this},y:function(t){return this._y=new u.Number(this.target.y()).morph(t),this},cx:function(t){return this._cx=new u.Number(this.target.cx()).morph(t),this},cy:function(t){return this._cy=new u.Number(this.target.cy()).morph(t),this},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},size:function(t,e){if(this.target instanceof u.Text)this.attr("font-size",t);else{var i=this.target.bbox();this._size={width:new u.Number(i.width).morph(t),height:new u.Number(i.height).morph(e)}}return this},plot:function(t){return this._plot=t,this},leading:function(t){return this.target._leading&&(this._leading=new u.Number(this.target._leading).morph(t)),this},viewbox:function(t,e,i,n){if(this.target instanceof u.Container){var r=this.target.viewbox();this._viewbox={x:new u.Number(r.x).morph(t),y:new u.Number(r.y).morph(e),width:new u.Number(r.width).morph(i),height:new u.Number(r.height).morph(n)}}return this},update:function(t){return this.target instanceof u.Stop&&(null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new u.Number(t.offset))),this},during:function(t){return this._during=t,this},after:function(t){return this._after=t,this},loop:function(t){return this._loop=t||!0,this},stop:function(t){return t===!0?(this.animate(0),this._after&&this._after.apply(this.target,[this])):(clearTimeout(this.timeout),this.attrs={},this.trans={},this.styles={},this.situation={},delete this._x,delete this._y,delete this._cx,delete this._cy,delete this._size,delete this._plot,delete this._loop,delete this._after,delete this._during,delete this._leading,delete this._viewbox),this},pause:function(){return this.situation.play===!0&&(this.situation.play=!1,this.situation.pause=(new Date).getTime()),this},play:function(){if(this.situation.play===!1){var t=(new Date).getTime()-this.situation.pause;this.situation.finish+=t,this.situation.start+=t,this.situation.play=!0}return this}},parent:u.Element,construct:{animate:function(t,e,i){return(this.fx||(this.fx=new u.FX(this))).stop().animate(t,e,i)},stop:function(t){return this.fx&&this.fx.stop(t),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this}}}),u.extend(u.Element,u.FX,{dx:function(t){return this.x((this.target||this).x()+t)},dy:function(t){return this.y((this.target||this).y()+t)},dmove:function(t,e){return this.dx(t).dy(e)}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach(function(t){u.Element.prototype[t]=function(e){var i=this;return this.node["on"+t]="function"==typeof e?function(){return e.apply(i,arguments)}:null,this}}),u.events={},u.listeners={},u.registerEvent=function(t){u.events[t]||(u.events[t]=new Event(t))},u.on=function(t,e,i){var n=i.bind(t.instance||t);u.listeners[i]=n,t.addEventListener(e,n,!1)},u.off=function(t,e,i){t.removeEventListener(e,u.listeners[i],!1),delete u.listeners[i]},u.extend(u.Element,{on:function(t,e){return u.on(this.node,t,e),this},off:function(t,e){return u.off(this.node,t,e),this},fire:function(t){return this.node.dispatchEvent(u.events[t]),this}}),u.Defs=u.invent({create:"defs",inherit:u.Container}),u.G=u.invent({create:"g",inherit:u.Container,extend:{x:function(t){return null==t?this.trans.x:this.transform("x",t)},y:function(t){return null==t?this.trans.y:this.transform("y",t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)}},construct:{group:function(){return this.put(new u.G)}}}),u.extend(u.Element,{siblings:function(){return this.parent.children()},position:function(){return this.parent.index(this)},next:function(){return this.siblings()[this.position()+1]},previous:function(){return this.siblings()[this.position()-1]},forward:function(){var t=this.position();return this.parent.removeElement(this).put(this,t+1)},backward:function(){var t=this.position();return t>0&&this.parent.removeElement(this).add(this,t-1),this},front:function(){return this.parent.removeElement(this).put(this)},back:function(){return this.position()>0&&this.parent.removeElement(this).add(this,0),this},before:function(t){t.remove();var e=this.position();return this.parent.add(t,e),this},after:function(t){t.remove();var e=this.position();return this.parent.add(t,e+1),this}}),u.Mask=u.invent({create:function(){this.constructor.call(this,u.create("mask")),this.targets=[]},inherit:u.Container,extend:{remove:function(){for(var t=this.targets.length-1;t>=0;t--)this.targets[t]&&this.targets[t].unmask();return delete this.targets,this.parent.removeElement(this),this}},construct:{mask:function(){return this.defs().put(new u.Mask)}}}),u.extend(u.Element,{maskWith:function(t){return this.masker=t instanceof u.Mask?t:this.parent.mask().add(t),this.masker.targets.push(this),this.attr("mask",'url("#'+this.masker.attr("id")+'")')},unmask:function(){return delete this.masker,this.attr("mask",null)}}),u.Clip=u.invent({create:function(){this.constructor.call(this,u.create("clipPath")),this.targets=[]},inherit:u.Container,extend:{remove:function(){for(var t=this.targets.length-1;t>=0;t--)this.targets[t]&&this.targets[t].unclip();return delete this.targets,this.parent.removeElement(this),this}},construct:{clip:function(){return this.defs().put(new u.Clip)}}}),u.extend(u.Element,{clipWith:function(t){return this.clipper=t instanceof u.Clip?t:this.parent.clip().add(t),this.clipper.targets.push(this),this.attr("clip-path",'url("#'+this.clipper.attr("id")+'")')},unclip:function(){return delete this.clipper,this.attr("clip-path",null)}}),u.Gradient=u.invent({create:function(t){this.constructor.call(this,u.create(t+"Gradient")),this.type=t},inherit:u.Container,extend:{from:function(t,e){return"radial"==this.type?this.attr({fx:new u.Number(t),fy:new u.Number(e)}):this.attr({x1:new u.Number(t),y1:new u.Number(e)})},to:function(t,e){return"radial"==this.type?this.attr({cx:new u.Number(t),cy:new u.Number(e)}):this.attr({x2:new u.Number(t),y2:new u.Number(e)})},radius:function(t){return"radial"==this.type?this.attr({r:new u.Number(t)}):this},at:function(t,e,i){return this.put(new u.Stop).update(t,e,i)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},fill:function(){return"url(#"+this.id()+")"},toString:function(){return this.fill()}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),u.extend(u.Defs,{gradient:function(t,e){return this.put(new u.Gradient(t)).update(e)}}),u.Stop=u.invent({create:"stop",inherit:u.Element,extend:{update:function(t){return("number"==typeof t||t instanceof u.Number)&&(t={offset:arguments[0],color:arguments[1],opacity:arguments[2]}),null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new u.Number(t.offset)),this}}}),u.Pattern=u.invent({create:"pattern",inherit:u.Container,extend:{fill:function(){return"url(#"+this.id()+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.fill()}},construct:{pattern:function(t,e,i){return this.defs().pattern(t,e,i)}}}),u.extend(u.Defs,{pattern:function(t,e,i){return this.put(new u.Pattern).update(i).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),u.Doc=u.invent({create:function(t){this.parent="string"==typeof t?document.getElementById(t):t,this.constructor.call(this,"svg"==this.parent.nodeName?this.parent:u.create("svg")),this.attr({xmlns:u.ns,version:"1.1",width:"100%",height:"100%"}).attr("xmlns:xlink",u.xlink,u.xmlns),this._defs=new u.Defs,this._defs.parent=this,this.node.appendChild(this._defs.node),this.doSpof=!1,this.parent!=this.node&&this.stage()},inherit:u.Container,extend:{stage:function(){var t=this;return this.parent.appendChild(this.node),t.spof(),u.on(window,"resize",function(){t.spof()}),this},defs:function(){return this._defs},spof:function(){if(this.doSpof){var t=this.node.getScreenCTM();t&&this.style("left",-t.e%1+"px").style("top",-t.f%1+"px")}return this},fixSubPixelOffset:function(){return this.doSpof=!0,this}}}),u.Shape=u.invent({create:function(t){this.constructor.call(this,t)},inherit:u.Element}),u.Symbol=u.invent({create:"symbol",inherit:u.Container,construct:{symbol:function(){return this.defs().put(new u.Symbol)}}}),u.Use=u.invent({create:"use",inherit:u.Shape,extend:{element:function(t){return this.target=t,this.attr("href","#"+t,u.xlink)}},construct:{use:function(t){return this.put(new u.Use).element(t)}}}),u.Rect=u.invent({create:"rect",inherit:u.Shape,construct:{rect:function(t,e){return this.put((new u.Rect).size(t,e))}}}),u.Ellipse=u.invent({create:"ellipse",inherit:u.Shape,extend:{x:function(t){return null==t?this.cx()-this.attr("rx"):this.cx(t+this.attr("rx"))},y:function(t){return null==t?this.cy()-this.attr("ry"):this.cy(t+this.attr("ry"))},cx:function(t){return null==t?this.attr("cx"):this.attr("cx",new u.Number(t).divide(this.trans.scaleX))},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",new u.Number(t).divide(this.trans.scaleY))},width:function(t){return null==t?2*this.attr("rx"):this.attr("rx",new u.Number(t).divide(2))},height:function(t){return null==t?2*this.attr("ry"):this.attr("ry",new u.Number(t).divide(2))},size:function(t,e){var i=n(this.bbox(),t,e);return this.attr({rx:new u.Number(i.width).divide(2),ry:new u.Number(i.height).divide(2)})}},construct:{circle:function(t){return this.ellipse(t,t)},ellipse:function(t,e){return this.put(new u.Ellipse).size(t,e).move(0,0)}}}),u.Line=u.invent({create:"line",inherit:u.Shape,extend:{x:function(t){var e=this.bbox();return null==t?e.x:this.attr({x1:this.attr("x1")-e.x+t,x2:this.attr("x2")-e.x+t})},y:function(t){var e=this.bbox();return null==t?e.y:this.attr({y1:this.attr("y1")-e.y+t,y2:this.attr("y2")-e.y+t})},cx:function(t){var e=this.bbox().width/2;return null==t?this.x()+e:this.x(t-e)},cy:function(t){var e=this.bbox().height/2;return null==t?this.y()+e:this.y(t-e)},width:function(t){var e=this.bbox();return null==t?e.width:this.attr(this.attr("x1")<this.attr("x2")?"x2":"x1",e.x+t)},height:function(t){var e=this.bbox();return null==t?e.height:this.attr(this.attr("y1")<this.attr("y2")?"y2":"y1",e.y+t)
+},size:function(t,e){var i=n(this.bbox(),t,e);return this.width(i.width).height(i.height)},plot:function(t,e,i,n){return this.attr({x1:t,y1:e,x2:i,y2:n})}},construct:{line:function(t,e,i,n){return this.put((new u.Line).plot(t,e,i,n))}}}),u.Polyline=u.invent({create:"polyline",inherit:u.Shape,construct:{polyline:function(t){return this.put(new u.Polyline).plot(t)}}}),u.Polygon=u.invent({create:"polygon",inherit:u.Shape,construct:{polygon:function(t){return this.put(new u.Polygon).plot(t)}}}),u.extend(u.Polyline,u.Polygon,{morphArray:u.PointArray,plot:function(t){return this.attr("points",this.array=new u.PointArray(t,[[0,0]]))},move:function(t,e){return this.attr("points",this.array.move(t,e))},x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},width:function(t){var e=this.bbox();return null==t?e.width:this.size(t,e.height)},height:function(t){var e=this.bbox();return null==t?e.height:this.size(e.width,t)},size:function(t,e){var i=n(this.bbox(),t,e);return this.attr("points",this.array.size(i.width,i.height))}}),u.Path=u.invent({create:"path",inherit:u.Shape,extend:{plot:function(t){return this.attr("d",this.array=new u.PathArray(t,[["M",0,0]]))},move:function(t,e){return this.attr("d",this.array.move(t,e))},x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},size:function(t,e){var i=n(this.bbox(),t,e);return this.attr("d",this.array.size(i.width,i.height))},width:function(t){return null==t?this.bbox().width:this.size(t,this.bbox().height)},height:function(t){return null==t?this.bbox().height:this.size(this.bbox().width,t)}},construct:{path:function(t){return this.put(new u.Path).plot(t)}}}),u.Image=u.invent({create:"image",inherit:u.Shape,extend:{load:function(t){if(!t)return this;var e=this,i=document.createElement("img");return i.onload=function(){var n=e.doc(u.Pattern);0==e.width()&&0==e.height()&&e.size(i.width,i.height),n&&0==n.width()&&0==n.height()&&n.size(e.width(),e.height()),"function"==typeof e._loaded&&e._loaded.call(e,{width:i.width,height:i.height,ratio:i.width/i.height,url:t})},this.attr("href",i.src=this.src=t,u.xlink)},loaded:function(t){return this._loaded=t,this}},construct:{image:function(t,e,i){return this.put(new u.Image).load(t).size(e||0,i||e||0)}}}),u.Text=u.invent({create:function(){this.constructor.call(this,u.create("text")),this._leading=new u.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",u.defaults.attrs["font-family"])},inherit:u.Shape,extend:{x:function(t){return null==t?this.attr("x"):(this.textPath||this.lines.each(function(){this.newLined&&this.x(t)}),this.attr("x",t))},y:function(t){var e=this.attr("y"),i="number"==typeof e?e-this.bbox().y:0;return null==t?"number"==typeof e?e-i:e:this.attr("y","number"==typeof t?t+i:t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)},text:function(t){if("undefined"==typeof t)return this.content;if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{t=(this.content=t).split("\n");for(var e=0,i=t.length;i>e;e++)this.tspan(t[e]).newLine()}return this.build(!1).rebuild()},size:function(t){return this.attr("font-size",t).rebuild()},leading:function(t){return null==t?this._leading:(this._leading=new u.Number(t),this.rebuild())},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this;this.lines.each(function(){this.newLined&&(this.textPath||this.attr("x",e.attr("x")),this.attr("dy",e._leading*new u.Number(e.attr("font-size"))))}),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this}},construct:{text:function(t){return this.put(new u.Text).text(t)},plain:function(t){return this.put(new u.Text).plain(t)}}}),u.TSpan=u.invent({create:"tspan",inherit:u.Shape,extend:{text:function(t){return"function"==typeof t?t.call(this,this):this.plain(t),this},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.doc(u.Text);return this.newLined=!0,this.dy(t._leading*t.attr("font-size")).attr("x",t.x())}}}),u.extend(u.Text,u.TSpan,{plain:function(t){return this._build===!1&&this.clear(),this.node.appendChild(document.createTextNode(this.content=t)),this},tspan:function(t){var e=(this.textPath||this).node,i=new u.TSpan;return this._build===!1&&this.clear(),e.appendChild(i.node),i.parent=this,this instanceof u.Text&&this.lines.add(i),i.text(t)},clear:function(){for(var t=(this.textPath||this).node;t.hasChildNodes();)t.removeChild(t.lastChild);return this instanceof u.Text&&(delete this.lines,this.lines=new u.Set,this.content=""),this},length:function(){return this.node.getComputedTextLength()}}),u.registerEvent("rebuild"),u.TextPath=u.invent({create:"textPath",inherit:u.Element,parent:u.Text,construct:{path:function(t){for(this.textPath=new u.TextPath;this.node.hasChildNodes();)this.textPath.node.appendChild(this.node.firstChild);return this.node.appendChild(this.textPath.node),this.track=this.doc().defs().path(t),this.textPath.parent=this,this.textPath.attr("href","#"+this.track,u.xlink),this},plot:function(t){return this.track&&this.track.plot(t),this}}}),u.Nested=u.invent({create:function(){this.constructor.call(this,u.create("svg")),this.style("overflow","visible")},inherit:u.Container,construct:{nested:function(){return this.put(new u.Nested)}}}),u.A=u.invent({create:"a",inherit:u.Container,extend:{to:function(t){return this.attr("href",t,u.xlink)},show:function(t){return this.attr("show",t,u.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new u.A).to(t)}}}),u.extend(u.Element,{linkTo:function(t){var e=new u.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent.put(e).put(this)}}),u.Marker=u.invent({create:"marker",inherit:u.Container,extend:{width:function(t){return this.attr("markerWidth",t)},height:function(t){return this.attr("markerHeight",t)},ref:function(t,e){return this.attr("refX",t).attr("refY",e)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return"url(#"+this.id()+")"}},construct:{marker:function(t,e,i){return this.defs().marker(t,e,i)}}}),u.extend(u.Defs,{marker:function(t,e,i){return this.put(new u.Marker).size(t,e).ref(t/2,e/2).viewbox(0,0,t,e).attr("orient","auto").update(i)}}),u.extend(u.Line,u.Polyline,u.Polygon,u.Path,{marker:function(t,e,i,n){var r=["marker"];return"all"!=t&&r.push(t),r=r.join("-"),t=arguments[1]instanceof u.Marker?arguments[1]:this.doc().marker(e,i,n),this.attr(r,t)}});var l={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(t,e){return"color"==e?t:t+"-"+e}};["fill","stroke"].forEach(function(t){var e,i={};i[t]=function(i){if("string"==typeof i||u.Color.isRgb(i)||i&&"function"==typeof i.fill)this.attr(t,i);else for(e=l[t].length-1;e>=0;e--)null!=i[l[t][e]]&&this.attr(l.prefix(t,l[t][e]),i[l[t][e]]);return this},u.extend(u.Element,u.FX,i)}),u.extend(u.Element,u.FX,{rotate:function(t,e,i){return this.transform({rotation:t||0,cx:e,cy:i})},skew:function(t,e){return this.transform({skewX:t||0,skewY:e||0})},scale:function(t,e){return this.transform({scaleX:t,scaleY:null==e?t:e})},translate:function(t,e){return this.transform({x:t,y:e})},matrix:function(t){return this.transform({matrix:t})},opacity:function(t){return this.attr("opacity",t)}}),u.extend(u.Rect,u.Ellipse,u.FX,{radius:function(t,e){return this.attr({rx:t,ry:e||t})}}),u.extend(u.Path,{length:function(){return this.node.getTotalLength()},pointAt:function(t){return this.node.getPointAtLength(t)}}),u.extend(u.Parent,u.Text,u.FX,{font:function(t){for(var e in t)"leading"==e?this.leading(t[e]):"anchor"==e?this.attr("text-anchor",t[e]):"size"==e||"family"==e||"weight"==e||"stretch"==e||"variant"==e||"style"==e?this.attr("font-"+e,t[e]):this.attr(e,t[e]);return this}}),u.Set=u.invent({create:function(){this.clear()},extend:{add:function(){var t,e,i=[].slice.call(arguments);for(t=0,e=i.length;e>t;t++)this.members.push(i[t]);return this},remove:function(t){var e=this.index(t);return e>-1&&this.members.splice(e,1),this},each:function(t){for(var e=0,i=this.members.length;i>e;e++)t.apply(this.members[e],[e,this.members]);return this},clear:function(){return this.members=[],this},has:function(t){return this.index(t)>=0},index:function(t){return this.members.indexOf(t)},get:function(t){return this.members[t]},first:function(){return this.get(0)},last:function(){return this.get(this.members.length-1)},valueOf:function(){return this.members},bbox:function(){var t=new u.BBox;if(0==this.members.length)return t;var e=this.members[0].rbox();return t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,this.each(function(){t=t.merge(this.rbox())}),t}},construct:{set:function(){return new u.Set}}}),u.SetFX=u.invent({create:function(t){this.set=t}}),u.Set.inherit=function(){var t,e=[];for(var t in u.Shape.prototype)"function"==typeof u.Shape.prototype[t]&&"function"!=typeof u.Set.prototype[t]&&e.push(t);e.forEach(function(t){u.Set.prototype[t]=function(){for(var e=0,i=this.members.length;i>e;e++)this.members[e]&&"function"==typeof this.members[e][t]&&this.members[e][t].apply(this.members[e],arguments);return"animate"==t?this.fx||(this.fx=new u.SetFX(this)):this}}),e=[];for(var t in u.FX.prototype)"function"==typeof u.FX.prototype[t]&&"function"!=typeof u.SetFX.prototype[t]&&e.push(t);e.forEach(function(t){u.SetFX.prototype[t]=function(){for(var e=0,i=this.set.members.length;i>e;e++)this.set.members[e].fx[t].apply(this.set.members[e].fx,arguments);return this}})},u.extend(u.Element,{data:function(t,e,i){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+t))}catch(n){return this.attr("data-"+t)}else this.attr("data-"+t,null===e?null:i===!0||"string"==typeof e||"number"==typeof e?e:JSON.stringify(e));return this}}),u.extend(u.Element,{remember:function(t,e){if("object"==typeof arguments[0])for(var e in t)this.remember(e,t[e]);else{if(1==arguments.length)return this.memory()[t];this.memory()[t]=e}return this},forget:function(){if(0==arguments.length)this._memory={};else for(var t=arguments.length-1;t>=0;t--)delete this.memory()[arguments[t]];return this},memory:function(){return this._memory||(this._memory={})}}),"function"==typeof define&&define.amd?define(function(){return u}):"undefined"!=typeof exports&&(exports.SVG=u),window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)}}()}).call(this);
\ No newline at end of file
index e67969e276e5189170dfe97793bd034f37a2d5ff..a7045763147d886497a363d8928281766626c5af 100755 (executable)
@@ -6,7 +6,7 @@
 , "keywords":     ["svg", "vector", "graphics", "animation"]
 , "author":       "Wout Fierens <wout@impinc.co.uk>"
 , "main":         "dist/svg.js"
-, "version":      "1.0.0-rc.8"
+, "version":      "1.0.0-rc.9"
 , "jam": {
     "include": [
       "dist/svg.js"
index 78d95d8c88c2ddc2fc729b51fd55e138c4317638..2dd41b2e68c240cda540e7de470067750fddfc75 100755 (executable)
@@ -29,6 +29,7 @@
 
 <!-- include spec files here... -->
 <script type="text/javascript" src="spec/svg.js"></script>
+<script type="text/javascript" src="spec/selector.js"></script>
 <script type="text/javascript" src="spec/regex.js"></script>
 <script type="text/javascript" src="spec/container.js"></script>
 <script type="text/javascript" src="spec/element.js"></script>
 <script type="text/javascript" src="spec/polyline.js"></script>
 <script type="text/javascript" src="spec/polygon.js"></script>
 <script type="text/javascript" src="spec/path.js"></script>
+<script type="text/javascript" src="spec/marker.js"></script>
 <script type="text/javascript" src="spec/image.js"></script>
 <script type="text/javascript" src="spec/text.js"></script>
 <script type="text/javascript" src="spec/textpath.js"></script>
 <script type="text/javascript" src="spec/doc.js"></script>
+<script type="text/javascript" src="spec/defs.js"></script>
 <script type="text/javascript" src="spec/group.js"></script>
 <script type="text/javascript" src="spec/set.js"></script>
 <script type="text/javascript" src="spec/gradient.js"></script>
 <script type="text/javascript" src="spec/pattern.js"></script>
 <script type="text/javascript" src="spec/use.js"></script>
+<script type="text/javascript" src="spec/symbol.js"></script>
 <script type="text/javascript" src="spec/mask.js"></script>
 <script type="text/javascript" src="spec/clip.js"></script>
 <script type="text/javascript" src="spec/color.js"></script>
diff --git a/spec/spec/defs.js b/spec/spec/defs.js
new file mode 100644 (file)
index 0000000..5e5da08
--- /dev/null
@@ -0,0 +1,12 @@
+describe('Defs', function() {
+  var defs
+
+  beforeEach(function() {
+    defs = draw.defs()
+  })
+
+  it('creates an instance of SVG.Defs', function() {
+    expect(defs instanceof SVG.Defs).toBeTruthy()
+  })
+
+})
\ No newline at end of file
index a0c7a2a7e7c832b848ecae40cc23bda6ea130bb4..5bda0d224ff7ccb2a485d4da2daeb3c3fb44f001 100755 (executable)
@@ -85,6 +85,22 @@ describe('Element', function() {
       expect(rect.attr().x).toBe('69%')
     })
   })
+
+  describe('id()', function() {
+    var rect
+    
+    beforeEach(function() {
+      rect = draw.rect(100,100)
+    })
+    
+    it('gets the value if the id attribute without an argument', function() {
+      expect(rect.id()).toBe(rect.attr('id'))
+    })
+    it('sets the value of the id', function() {
+      rect.id('new_id')
+      expect(rect.attr('id')).toBe('new_id')
+    })
+  })
   
   describe('style()', function() {
     it('should set the style with key and value arguments', function() {
@@ -384,17 +400,27 @@ describe('Element', function() {
       element.toggleClass('one')
       expect(element.hasClass('one')).toBeTruthy()
     })
-
     it('removes the class when it already exists', function(){
       var element = draw.rect(100,100)
       element.addClass('one')
       element.toggleClass('one')
       expect(element.hasClass('one')).toBeFalsy()
     })
-
     it('returns the svg instance', function() {
       var element = draw.rect(100,100)
       expect(element.toggleClass('one')).toEqual(element)
     })
   })
+
+  describe('reference()', function() {
+    it('gets a referenced element from a given attribute', function() {
+      var rect = draw.defs().rect(100, 100)
+        , use  = draw.use(rect)
+        , mark = draw.marker(10, 10)
+        , path = draw.path(svgPath).marker('end', mark)
+
+      expect(use.reference('href')).toBe(rect)
+      expect(path.reference('marker-end')).toBe(mark)
+    })
+  })
 })
index 552ca6cbfc1338524e98c40438a7e01ae0b311b5..e3cba616adc5c3c759bb84f2729e55757856b0fc 100755 (executable)
@@ -15,7 +15,7 @@ loremIpsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras soda
 
 /* approximately helper */
 function approximately(number, precision) {
-  precision = precision == null ? 2.5 : precision
+  precision = precision == null ? 1.5 : precision
   
   return Math.round(number / precision) * precision
 }
diff --git a/spec/spec/marker.js b/spec/spec/marker.js
new file mode 100644 (file)
index 0000000..8d18c85
--- /dev/null
@@ -0,0 +1,89 @@
+describe('Marker', function() {
+  
+  describe('on a container element', function() {
+    var marker
+
+    beforeEach(function() {
+      marker = draw.marker(10, 12, function(add) {
+        add.rect(10, 12)
+
+        this.ref(5, 6)
+      })
+    })
+
+    it('creates an instance of SVG.Marker', function() {
+      expect(marker instanceof SVG.Marker).toBeTruthy()
+    })
+
+    it('creates marker in defs', function() {
+      expect(marker.parent instanceof SVG.Defs).toBeTruthy()
+    })
+
+    describe('marker()', function() {
+      it('returns the marker element', function() {
+        expect(marker = draw.marker(10, 12)).toBe(marker)
+      })
+      it('sets the refX to half of the given width', function() {
+        marker = draw.marker(10, 12)
+        expect(marker.node.getAttribute('refX')).toBe('5')
+      })
+      it('sets the refY to half of the given height', function() {
+        marker = draw.marker(13, 15)
+        expect(marker.node.getAttribute('refY')).toBe('7.5')
+      })
+    })
+
+  })
+  
+  describe('on a target path', function() {
+    var path, marker
+
+    beforeEach(function() {
+      path = draw.path('M 100 200 C 200 100 300  0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100')
+
+      path.marker('mid', 10, 12, function(add) {
+        add.rect(10, 12)
+
+        this.ref(5, 6)
+      })
+
+      marker = path.marker('mid')
+    })
+
+    it('creates an instance of SVG.Marker', function() {
+      expect(path.reference('marker-mid') instanceof SVG.Marker).toBeTruthy()
+    })
+
+    describe('marker()', function() {
+      it('returns the target element', function() {
+        expect(path.marker('start', 10, 12)).toBe(path)
+      })
+      it('creates a marker and applies it to the marker-start attribute', function() {
+        path.marker('start', 10, 12)
+        marker = path.reference('marker-start')
+
+        expect(path.node.getAttribute('marker-start')).toBe(marker.toString())
+      })
+      it('creates a marker and applies it to the marker-mid attribute', function() {
+        path.marker('mid', 10, 12)
+        marker = path.reference('marker-mid')
+
+        expect(path.node.getAttribute('marker-mid')).toBe(marker.toString())
+      })
+      it('creates a marker and applies it to the marker-end attribute', function() {
+        path.marker('end', 10, 12)
+        marker = path.reference('marker-end')
+
+        expect(path.node.getAttribute('marker-end')).toBe(marker.toString())
+      })
+      it('accepts an instance of an existing marker element as the second argument', function() {
+        marker = draw.marker(11, 11)
+        path.marker('mid', marker)
+
+        expect(path.node.getAttribute('marker-mid')).toBe(marker.toString())
+      })
+    })
+  })
+
+
+})
\ No newline at end of file
index f64991a812f14c96e407eae1de6d084c81682d74..4b36175a090d56d0dab963334679751fa20bedc5 100644 (file)
@@ -1,26 +1,37 @@
 describe('Regex', function() {
 
-  describe('unit', function() {
-    it('is true with a positive unit value', function() {
-      expect(SVG.regex.unit.test('10%')).toBeTruthy()
-    })
-    it('is true with a negative unit value', function() {
-      expect(SVG.regex.unit.test('-11%')).toBeTruthy()
-    })
-    it('is false with a positive unit value', function() {
-      expect(SVG.regex.unit.test('NotAUnit')).toBeFalsy()
+  describe('matchers', function() {
+    describe('unit', function() {
+      var match
+
+      it('is true with a positive unit value', function() {
+        match = ('10%').match(SVG.regex.unit)
+        expect(match[1]).toBe('10')
+        expect(match[2]).toBe('%')
+      })
+      it('is true with a negative unit value', function() {
+        match = ('-11%').match(SVG.regex.unit)
+        expect(match[1]).toBe('-11')
+        expect(match[2]).toBe('%')
+      })
+      it('is false with a positive unit value', function() {
+        match = ('NotAUnit').match(SVG.regex.unit)
+        expect(match).toBeNull()
+      })
     })
   })
 
-  describe('isEvent', function() {
-    it('is true with a namespaced and lowercase name', function() {
-      expect(SVG.regex.isEvent.test('my:event')).toBeTruthy()
-    })
-    it('is true with a namespaced and camelCase name', function() {
-      expect(SVG.regex.isEvent.test('mt:fabulousEvent')).toBeTruthy()
-    })
-    it('is false without a namespace', function() {
-      expect(SVG.regex.isEvent.test('idontlinkenamespaces')).toBeFalsy()
+  describe('testers', function() {
+    describe('isEvent', function() {
+      it('is true with a namespaced and lowercase name', function() {
+        expect(SVG.regex.isEvent.test('my:event')).toBeTruthy()
+      })
+      it('is true with a namespaced and camelCase name', function() {
+        expect(SVG.regex.isEvent.test('mt:fabulousEvent')).toBeTruthy()
+      })
+      it('is false without a namespace', function() {
+        expect(SVG.regex.isEvent.test('idontlinkenamespaces')).toBeFalsy()
+      })
     })
   })
 
diff --git a/spec/spec/selector.js b/spec/spec/selector.js
new file mode 100644 (file)
index 0000000..4727bfd
--- /dev/null
@@ -0,0 +1,27 @@
+describe('Selector', function() {
+
+  describe('get()', function() {
+    it('gets an element\'s instance by id', function() {
+      var rect = draw.rect(111, 333)
+      
+      expect(SVG.get(rect.attr('id'))).toBe(rect)
+    })
+    it('makes all the element\'s methods available', function() {
+      var element = draw.group()
+        , got = SVG.get(element.attr('id'))
+      
+      expect(got.transform()).toEqual(SVG.defaults.trans())
+      expect(got.attr()).toEqual(element.attr())
+    })
+    it('gets a referenced element by attribute value', function() {
+      var rect = draw.defs().rect(100, 100)
+        , use  = draw.use(rect)
+        , mark = draw.marker(10, 10)
+        , path = draw.path(svgPath).marker('end', mark)
+
+      expect(SVG.get(use.attr('href'))).toBe(rect)
+      expect(SVG.get(path.attr('marker-end'))).toBe(mark)
+    })
+  })
+  
+})
\ No newline at end of file
index 0eb822d6b21a1fc4600f1b203aa28f7f558e6355..1238ee707df5142f94772a1357cb66e578802d37 100755 (executable)
@@ -16,7 +16,7 @@ describe('Set', function() {
   })
 
   it('creates the set method on SVG.Container instances', function() {
-    expect(draw.set() instanceof SVG.Set).toBe(true)
+    expect(draw.set() instanceof SVG.Set).toBeTruthy()
   })
 
   describe('add()', function() {
@@ -75,16 +75,30 @@ describe('Set', function() {
   })
 
   describe('get()', function() {
-    it('returns member ar given index', function() {
+    it('returns member at given index', function() {
       set.add(e1).add(e2).add(e3).add(e4).add(e5)
       expect(set.get(2)).toBe(e3)
     })
   })
 
+  describe('first()', function() {
+    it('returns first member', function() {
+      set.add(e1).add(e2).add(e3).add(e4).add(e5)
+      expect(set.first()).toBe(e1)
+    })
+  })
+
+  describe('last()', function() {
+    it('returns last member', function() {
+      set.add(e1).add(e2).add(e3).add(e4).add(e5)
+      expect(set.last()).toBe(e5)
+    })
+  })
+
   describe('has()', function() {
     it('checks if a given element is present in set', function() {
       set.add(e1).add(e2).add(e3).add(e4).add(e5)
-      expect(set.has(e4)).toBe(true)
+      expect(set.has(e4)).toBeTruthy()
     })
   })
 
@@ -120,7 +134,7 @@ describe('Set', function() {
     it('returns an instance of SVG.BBox', function() {
       set.add(e1).add(e2).add(e3).add(e4).add(e5)
 
-      expect(set.bbox() instanceof SVG.BBox).toBe(true)
+      expect(set.bbox() instanceof SVG.BBox).toBeTruthy()
     })
     it('returns an empty bounding box wiht no members', function() {
       var box = set.bbox()
index 843bb89706230fa8b0175dcd08461f3636ca758f..cc9f7be47388d6e671305a66f9f260f5664d4f6c 100755 (executable)
@@ -79,19 +79,4 @@ describe('SVG', function() {
     })
   })
   
-  describe('get()', function() {
-    it('gets an element\'s instance by id', function() {
-      var rect = draw.rect(111,333)
-      
-      expect(SVG.get(rect.attr('id'))).toBe(rect)
-    })
-    it('makes have all the element\'s methods available', function() {
-      var element = draw.group()
-        , got = SVG.get(element.attr('id'))
-      
-      expect(got.transform()).toEqual(SVG.defaults.trans())
-      expect(got.attr()).toEqual(element.attr())
-    })
-  })
-  
 })
\ No newline at end of file
diff --git a/spec/spec/symbol.js b/spec/spec/symbol.js
new file mode 100644 (file)
index 0000000..39a48db
--- /dev/null
@@ -0,0 +1,16 @@
+describe('Symbol', function() {
+  var symbol
+
+  beforeEach(function() {
+    symbol = draw.symbol()
+  })
+
+  it('creates an instance of SVG.Symbol', function() {
+    expect(symbol instanceof SVG.Symbol).toBeTruthy()
+  })
+
+  it('creates symbol in defs', function() {
+    expect(symbol.parent instanceof SVG.Defs).toBeTruthy()
+  })
+
+})
\ No newline at end of file
index 2e373a47c898700f8bda7e08fb0cb366e4e0fa93..9574b4c7141a2221bf00a9aa91d68f250e24982c 100755 (executable)
@@ -20,12 +20,12 @@ describe('Text', function() {
     it('sets the value of x with the first argument', function() {
       text.x(123)
       var box = text.bbox()
-      expect(box.x).toBe(123)
+      expect(approximately(box.x)).toBe(123)
     })
     it('sets the value of x based on the anchor with the first argument', function() {
       text.x(123, true)
       var box = text.bbox()
-      expect(box.x).toBe(123)
+      expect(approximately(box.x)).toBe(123)
     })
   })
   
@@ -50,17 +50,17 @@ describe('Text', function() {
   describe('cx()', function() {
     it('returns the value of cx without an argument', function() {
       var box = text.bbox()
-      expect(text.cx()).toBe(box.width / 2)
+      expect(approximately(text.cx())).toBe(approximately(box.width / 2))
     })
     it('sets the value of cx with the first argument', function() {
       text.cx(123)
       var box = text.bbox()
-      expect(box.cx).toBe(123)
+      expect(approximately(box.cx)).toBe(123)
     })
     it('sets the value of cx based on the anchor with the first argument', function() {
       text.cx(123, true)
       var box = text.bbox()
-      expect(box.cx).toBe(123)
+      expect(approximately(box.cx)).toBe(123)
     })
   })
   
@@ -80,8 +80,8 @@ describe('Text', function() {
     it('sets the x and y position', function() {
       text.move(123,456)
       var box = text.bbox()
-      expect(box.x).toBe(123)
-      expect(box.y).toBe(456)
+      expect(approximately(box.x)).toBe(123)
+      expect(approximately(box.y)).toBe(456)
     })
   })
   
@@ -89,8 +89,8 @@ describe('Text', function() {
     it('sets the cx and cy position', function() {
       text.center(321,567)
       var box = text.bbox()
-      expect(box.cx).toBe(321)
-      expect(Math.round(box.cy * 10) / 10).toBe(567)
+      expect(approximately(box.cx)).toBe(321)
+      expect(approximately(box.cy)).toBe(567)
     })
   })
   
@@ -199,8 +199,17 @@ describe('Text', function() {
     it('clears the stored content value', function() {
       text.text('Stored locally.')
       expect(text.content).toBe('Stored locally.')
-      text.clear()
-      expect(text.content).toBe('')
+    })
+  })
+
+  describe('length()', function() {
+    it('gets total length of text', function() {
+      text.text(function(add) {
+        add.tspan('The first.')
+        add.tspan('The second.')
+        add.tspan('The third.')
+      })
+      expect(text.length()).toBe(text.lines.get(0).length() + text.lines.get(1).length() + text.lines.get(2).length())
     })
   })
   
index a50ad94157cf4811417a0e74025335142878cf3e..ad66cc5e6a16bf1b6b0fc496b905795354bd0498 100755 (executable)
@@ -5,4 +5,5 @@ SVG.Defs = SVG.invent({
 
   // Inherit from
 , inherit: SVG.Container
+  
 })
\ No newline at end of file
index e63b57e7c98eeb15bd0e3160a76f50fafddbc63b..b12947b66a0ae79759f1c0b98732948d4cfb418c 100755 (executable)
@@ -61,10 +61,9 @@ SVG.Element = SVG.invent({
   , size: function(width, height) {
       var p = proportionalSize(this.bbox(), width, height)
 
-      return this.attr({
-        width:  new SVG.Number(p.width)
-      , height: new SVG.Number(p.height)
-      })
+      return this
+        .width(new SVG.Number(p.width))
+        .height(new SVG.Number(p.height))
     }
     // Clone element
   , clone: function() {
@@ -308,6 +307,10 @@ SVG.Element = SVG.invent({
       
       return this
     }
+    // Get / set id
+  , id: function(id) {
+      return this.attr('id', id)
+    }
     // Get bounding box
   , bbox: function() {
       return new SVG.BBox(this)
@@ -384,6 +387,10 @@ SVG.Element = SVG.invent({
       }
       return this
     }
+    // Get referenced element form attribute value
+  , reference: function(attr) {
+      return SVG.get(this.attr(attr))
+    }
     // Private: find svg parent by instance
   , _parent: function(parent) {
       var element = this
index 895f8ca6a8038eb1ec0ca91070b13620670e593c..56c1376c9fb2a5bd2c422e6bf793b77318da07de 100755 (executable)
@@ -47,7 +47,7 @@ SVG.Gradient = SVG.invent({
     }
     // Return the fill id
   , fill: function() {
-      return 'url(#' + this.attr('id') + ')'
+      return 'url(#' + this.id() + ')'
     }
     // Alias string convertion to fill
   , toString: function() {
index 5a1dd6d9725ca824995f40c21838c44b164e4978..c63c215d2e2c571ea285a650740f2351bea37522 100644 (file)
@@ -114,6 +114,13 @@ function parseMatrix(o) {
   return o
 }
 
+// Get id from reference string
+function idFromReference(url) {
+  var m = url.toString().match(SVG.regex.reference)
+
+  if (m) return m[1]
+}
+
 // Shim layer with setTimeout fallback by Paul Irish
 window.requestAnimFrame = (function(){
   return  window.requestAnimationFrame       ||
diff --git a/src/marker.js b/src/marker.js
new file mode 100644 (file)
index 0000000..30b09a4
--- /dev/null
@@ -0,0 +1,80 @@
+SVG.Marker = SVG.invent({
+  // Initialize node
+  create: 'marker'
+
+  // Inherit from
+, inherit: SVG.Container
+
+  // Add class methods
+, extend: {
+    // Set width of element
+    width: function(width) {
+      return this.attr('markerWidth', width)
+    }
+    // Set height of element
+  , height: function(height) {
+      return this.attr('markerHeight', height)
+    }
+    // Set marker refX and refY
+  , ref: function(x, y) {
+      return this.attr('refX', x).attr('refY', y)
+    }
+    // Update marker
+  , update: function(block) {
+      /* remove all content */
+      this.clear()
+      
+      /* invoke passed block */
+      if (typeof block == 'function')
+        block.call(this, this)
+      
+      return this
+    }
+    // Return the fill id
+  , toString: function() {
+      return 'url(#' + this.id() + ')'
+    }
+  }
+
+  // Add parent method
+, construct: {
+    marker: function(width, height, block) {
+      // Create marker element in defs
+      return this.defs().marker(width, height, block)
+    }
+  }
+
+})
+
+SVG.extend(SVG.Defs, {
+  // Create marker
+  marker: function(width, height, block) {
+    // Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto
+    return this.put(new SVG.Marker)
+      .size(width, height)
+      .ref(width / 2, height / 2)
+      .viewbox(0, 0, width, height)
+      .attr('orient', 'auto')
+      .update(block)
+  }
+  
+})
+
+SVG.extend(SVG.Line, SVG.Polyline, SVG.Polygon, SVG.Path, {
+  // Create and attach markers
+  marker: function(marker, width, height, block) {
+    var attr = ['marker']
+
+    // Build attribute name
+    if (marker != 'all') attr.push(marker)
+    attr = attr.join('-')
+
+    // Set marker attribute
+    marker = arguments[1] instanceof SVG.Marker ?
+      arguments[1] :
+      this.doc().marker(width, height, block)
+    
+    return this.attr(attr, marker)
+  }
+  
+})
\ No newline at end of file
index e5398d2396d879c9d9a9c9ef813a372967326fff..76190ef59b290546c8c11d1c377b442dd0cbb083 100755 (executable)
@@ -9,7 +9,7 @@ SVG.Pattern = SVG.invent({
 , extend: {
     // Return the fill id
          fill: function() {
-           return 'url(#' + this.attr('id') + ')'
+           return 'url(#' + this.id() + ')'
          }
          // Update pattern by rebuilding
        , update: function(block) {
index 433952b499063a4584b1afd29de3bda4f3040f30..13f62d817c15014be1ac8bd8d3e11d678bd51c47 100755 (executable)
@@ -8,6 +8,9 @@ SVG.regex = {
   
   /* parse rgb value */
 , rgb:          /rgb\((\d+),(\d+),(\d+)\)/
+  
+  /* parse reference id */
+, reference:    /#([a-z0-9\-_]+)/i
 
   /* test hex value */
 , isHex:        /^#[a-f0-9]{3,6}$/i
diff --git a/src/selector.js b/src/selector.js
new file mode 100644 (file)
index 0000000..905e9f9
--- /dev/null
@@ -0,0 +1,5 @@
+// Method for getting an element by id
+SVG.get = function(id) {
+  var node = document.getElementById(idFromReference(id) || id)
+  if (node) return node.instance
+}
\ No newline at end of file
index 38251f52835f414729b448019f6a1ff13a37377c..37246fe7f3c5ee369d33aada7514a6c071ba1575 100755 (executable)
@@ -52,6 +52,14 @@ SVG.Set = SVG.invent({
   , get: function(i) {
       return this.members[i]
     }
+    // Get first member
+  , first: function() {
+      return this.get(0)
+    }
+    // Get last member
+  , last: function() {
+      return this.get(this.members.length - 1)
+    }
     // Default value
   , valueOf: function() {
       return this.members
index e0e5b44adec6a1feb6de56e3fe46037a0b92e347..eb0185dcdd0699af6f4c40d6a92d276fa5ba2c30 100755 (executable)
@@ -55,12 +55,6 @@ SVG.extend = function() {
     SVG.Set.inherit()
 }
 
-// Method for getting an element by id
-SVG.get = function(id) {
-  var node = document.getElementById(id)
-  if (node) return node.instance
-}
-
 // Initialize parsing element
 SVG.prepare = function(element) {
   /* select document body and create invisible svg element */
diff --git a/src/symbol.js b/src/symbol.js
new file mode 100644 (file)
index 0000000..e8907a3
--- /dev/null
@@ -0,0 +1,17 @@
+
+SVG.Symbol = SVG.invent({
+  // Initialize node
+  create: 'symbol'
+
+  // Inherit from
+, inherit: SVG.Container
+
+  // Add parent method
+, construct: {
+    // Create a new symbol
+    symbol: function() {
+      return this.defs().put(new SVG.Symbol)
+    }
+  }
+  
+})
\ No newline at end of file
index 1d053620e3b3f0d226179e33697f3f236240ebb0..1b6bd9452945aa5dd2b660a7e552b225737b2ea2 100755 (executable)
@@ -217,6 +217,10 @@ SVG.extend(SVG.Text, SVG.TSpan, {
     
     return this
   }
+  // Get length of text element
+, length: function() {
+    return this.node.getComputedTextLength()
+  }
 })
 
 // Register rebuild event