aboutsummaryrefslogtreecommitdiffstats
path: root/dist
diff options
context:
space:
mode:
authorwout <wout@impinc.co.uk>2014-02-03 15:14:47 +0100
committerwout <wout@impinc.co.uk>2014-02-03 15:14:47 +0100
commite2304534e0cfb6f6f4ab8c37ea5275ae26cd455a (patch)
tree2386e9f361d9c5fa1308387aeeaf33f00241b3c5 /dist
parent7a29817ffd764cf7ab6906250b57f234801c94e0 (diff)
downloadsvg.js-e2304534e0cfb6f6f4ab8c37ea5275ae26cd455a.tar.gz
svg.js-e2304534e0cfb6f6f4ab8c37ea5275ae26cd455a.zip
Implemented SVG.invent function and bumped to v1.0rc3
Diffstat (limited to 'dist')
-rw-r--r--dist/svg.js2797
-rw-r--r--dist/svg.min.js4
2 files changed, 1428 insertions, 1373 deletions
diff --git a/dist/svg.js b/dist/svg.js
index 0aa269e..4a4f9db 100644
--- a/dist/svg.js
+++ b/dist/svg.js
@@ -1,12 +1,15 @@
-/* svg.js v1.0rc2-15-g3754d89 - svg regex default color array pointarray patharray number viewbox bbox rbox element parent container fx relative event defs group arrange mask clip gradient doc shape use rect ellipse line poly path image text textpath nested hyperlink sugar set data memory loader - svgjs.com/license */
+/* svg.js v1.0rc3 - svg inventor regex default color array pointarray patharray number viewbox bbox rbox element parent container fx relative event defs group arrange mask clip gradient doc shape use rect ellipse line poly path image text textpath nested hyperlink sugar set data memory loader - svgjs.com/license */
;(function() {
this.SVG = function(element) {
- if (!SVG.parser)
- SVG.prepare()
+ if (SVG.supported) {
+ element = new SVG.Doc(element)
- if (SVG.supported)
- return new SVG.Doc(element)
+ if (!SVG.parser)
+ SVG.prepare(element)
+
+ return element
+ }
}
// Default namespaces
@@ -60,15 +63,15 @@
}
// Initialize parsing element
- SVG.prepare = function() {
- /* select document body and create svg element*/
- var body = document.getElementsByTagName('body')[0] || document.getElementsByTagName('svg')[0]
- , draw = new SVG.Doc(body).size(2, 2).style('opacity:0;position:fixed;left:100%;top:100%;')
+ SVG.prepare = function(element) {
+ /* select document body and create invisible svg element */
+ var body = document.getElementsByTagName('body')[0]
+ , draw = (body ? new SVG.Doc(body) : element.nested()).size(2, 2)
/* create parser object */
SVG.parser = {
- body: body
- , draw: draw
+ body: body || element.parent
+ , draw: draw.style('opacity:0;position:fixed;left:100%;top:100%;overflow:hidden')
, poly: draw.polygon().node
, path: draw.path().node
}
@@ -82,6 +85,29 @@
if (!SVG.supported) return false
+ SVG.invent = function(config) {
+ /* create element initializer */
+ var initializer = typeof config.create == 'function' ?
+ config.create :
+ function() {
+ this.constructor.call(this, SVG.create(config.create))
+ }
+
+ /* inherit prototype */
+ if (config.inherit)
+ initializer.prototype = new config.inherit
+
+ /* extend with methods */
+ if (config.extend)
+ SVG.extend(initializer, config.extend)
+
+ /* attach construct method to parent */
+ if (config.construct)
+ SVG.extend(config.parent || SVG.Container, config.construct)
+
+ return initializer
+ }
+
SVG.regex = {
/* test a given value */
test: function(value, test) {
@@ -1044,548 +1070,559 @@
})
- SVG.Element = function(node) {
- /* make stroke value accessible dynamically */
- this._stroke = SVG.defaults.attrs.stroke
-
- /* initialize style store */
- this.styles = {}
-
- /* initialize transformation store with defaults */
- this.trans = SVG.defaults.trans()
-
- /* keep reference to the element node */
- if (this.node = node) {
- this.type = node.nodeName
- this.node.instance = this
+ SVG.Element = SVG.invent({
+ // Initialize node
+ create: function(node) {
+ /* make stroke value accessible dynamically */
+ this._stroke = SVG.defaults.attrs.stroke
+
+ /* initialize style store */
+ this.styles = {}
+
+ /* initialize transformation store with defaults */
+ this.trans = SVG.defaults.trans()
+
+ /* keep reference to the element node */
+ if (this.node = node) {
+ this.type = node.nodeName
+ this.node.instance = this
+ }
}
- }
- //
- SVG.extend(SVG.Element, {
- // Move over x-axis
- x: function(x) {
- if (x) {
- x = new SVG.Number(x)
- x.value /= this.trans.scaleX
+ // Add class methods
+ , extend: {
+ // Move over x-axis
+ x: function(x) {
+ if (x) {
+ x = new SVG.Number(x)
+ x.value /= this.trans.scaleX
+ }
+ return this.attr('x', x)
}
- return this.attr('x', x)
- }
- // Move over y-axis
- , y: function(y) {
- if (y) {
- y = new SVG.Number(y)
- y.value /= this.trans.scaleY
+ // Move over y-axis
+ , y: function(y) {
+ if (y) {
+ y = new SVG.Number(y)
+ y.value /= this.trans.scaleY
+ }
+ return this.attr('y', y)
}
- return this.attr('y', y)
- }
- // Move by center over x-axis
- , cx: function(x) {
- return x == null ? this.x() + this.width() / 2 : this.x(x - this.width() / 2)
- }
- // Move by center over y-axis
- , cy: function(y) {
- return y == null ? this.y() + this.height() / 2 : this.y(y - this.height() / 2)
- }
- // Move element to given x and y values
- , move: function(x, y) {
- return this.x(x).y(y)
- }
- // Move element by its center
- , center: function(x, y) {
- return this.cx(x).cy(y)
- }
- // Set width of element
- , width: function(width) {
- return this.attr('width', width)
- }
- // Set height of element
- , height: function(height) {
- return this.attr('height', height)
- }
- // Set element size to given width and height
- , size: function(width, height) {
- var p = this._proportionalSize(width, height)
-
- return this.attr({
- width: new SVG.Number(p.width)
- , height: new SVG.Number(p.height)
- })
- }
- // Clone element
- , clone: function() {
- var clone , attr
- , type = this.type
-
- /* invoke shape method with shape-specific arguments */
- clone = type == 'rect' || type == 'ellipse' ?
- this.parent[type](0,0) :
- type == 'line' ?
- this.parent[type](0,0,0,0) :
- type == 'image' ?
- this.parent[type](this.src) :
- type == 'text' ?
- this.parent[type](this.content) :
- type == 'path' ?
- this.parent[type](this.attr('d')) :
- type == 'polyline' || type == 'polygon' ?
- this.parent[type](this.attr('points')) :
- type == 'g' ?
- this.parent.group() :
- this.parent[type]()
-
- /* apply attributes attributes */
- attr = this.attr()
- delete attr.id
- clone.attr(attr)
-
- /* copy transformations */
- clone.trans = this.trans
-
- /* apply attributes and translations */
- return clone.transform({})
- }
- // Remove element
- , remove: function() {
- if (this.parent)
- this.parent.removeElement(this)
-
- return this
- }
- // Replace element
- , replace: function(element) {
- this.after(element).remove()
+ // Move by center over x-axis
+ , cx: function(x) {
+ return x == null ? this.x() + this.width() / 2 : this.x(x - this.width() / 2)
+ }
+ // Move by center over y-axis
+ , cy: function(y) {
+ return y == null ? this.y() + this.height() / 2 : this.y(y - this.height() / 2)
+ }
+ // Move element to given x and y values
+ , move: function(x, y) {
+ return this.x(x).y(y)
+ }
+ // Move element by its center
+ , center: function(x, y) {
+ return this.cx(x).cy(y)
+ }
+ // Set width of element
+ , width: function(width) {
+ return this.attr('width', width)
+ }
+ // Set height of element
+ , height: function(height) {
+ return this.attr('height', height)
+ }
+ // Set element size to given width and height
+ , size: function(width, height) {
+ var p = this._proportionalSize(width, height)
- return element
- }
- // Add element to given container and return self
- , addTo: function(parent) {
- return parent.put(this)
- }
- // Add element to given container and return container
- , putIn: function(parent) {
- return parent.add(this)
- }
- // Get parent document
- , doc: function(type) {
- return this._parent(type || SVG.Doc)
- }
- // Set svg element attribute
- , attr: function(a, v, n) {
- if (a == null) {
- /* get an object of attributes */
- a = {}
- v = this.node.attributes
- for (n = v.length - 1; n >= 0; n--)
- a[v[n].nodeName] = SVG.regex.test(v[n].nodeValue, 'isNumber') ? parseFloat(v[n].nodeValue) : v[n].nodeValue
+ return this.attr({
+ width: new SVG.Number(p.width)
+ , height: new SVG.Number(p.height)
+ })
+ }
+ // Clone element
+ , clone: function() {
+ var clone , attr
+ , type = this.type
- return a
+ /* invoke shape method with shape-specific arguments */
+ clone = type == 'rect' || type == 'ellipse' ?
+ this.parent[type](0,0) :
+ type == 'line' ?
+ this.parent[type](0,0,0,0) :
+ type == 'image' ?
+ this.parent[type](this.src) :
+ type == 'text' ?
+ this.parent[type](this.content) :
+ type == 'path' ?
+ this.parent[type](this.attr('d')) :
+ type == 'polyline' || type == 'polygon' ?
+ this.parent[type](this.attr('points')) :
+ type == 'g' ?
+ this.parent.group() :
+ this.parent[type]()
- } else if (typeof a == 'object') {
- /* apply every attribute individually if an object is passed */
- for (v in a) this.attr(v, a[v])
+ /* apply attributes attributes */
+ attr = this.attr()
+ delete attr.id
+ clone.attr(attr)
+
+ /* copy transformations */
+ clone.trans = this.trans
+
+ /* apply attributes and translations */
+ return clone.transform({})
+ }
+ // Remove element
+ , remove: function() {
+ if (this.parent)
+ this.parent.removeElement(this)
+
+ return this
+ }
+ // Replace element
+ , replace: function(element) {
+ this.after(element).remove()
+
+ return element
+ }
+ // Add element to given container and return self
+ , addTo: function(parent) {
+ return parent.put(this)
+ }
+ // Add element to given container and return container
+ , putIn: function(parent) {
+ return parent.add(this)
+ }
+ // Get parent document
+ , doc: function(type) {
+ return this._parent(type || SVG.Doc)
+ }
+ // Set svg element attribute
+ , attr: function(a, v, n) {
+ if (a == null) {
+ /* get an object of attributes */
+ a = {}
+ v = this.node.attributes
+ for (n = v.length - 1; n >= 0; n--)
+ a[v[n].nodeName] = SVG.regex.test(v[n].nodeValue, 'isNumber') ? parseFloat(v[n].nodeValue) : v[n].nodeValue
+
+ return a
+
+ } else if (typeof a == 'object') {
+ /* apply every attribute individually if an object is passed */
+ for (v in a) this.attr(v, a[v])
+
+ } else if (v === null) {
+ /* remove value */
+ this.node.removeAttribute(a)
+
+ } else if (v == null) {
+ /* act as a getter for style attributes */
+ if (this._isStyle(a)) {
+ return a == 'text' ?
+ this.content :
+ a == 'leading' && this.leading ?
+ this.leading() :
+ this.style(a)
+
+ /* act as a getter if the first and only argument is not an object */
+ } else {
+ v = this.node.getAttribute(a)
+ return v == null ?
+ SVG.defaults.attrs[a] :
+ SVG.regex.test(v, 'isNumber') ?
+ parseFloat(v) : v
+ }
+
+ } else if (a == 'style') {
+ /* redirect to the style method */
+ return this.style(v)
- } else if (v === null) {
- /* remove value */
- this.node.removeAttribute(a)
-
- } else if (v == null) {
- /* act as a getter for style attributes */
- if (this._isStyle(a)) {
- return a == 'text' ?
- this.content :
- a == 'leading' && this.leading ?
- this.leading() :
- this.style(a)
-
- /* act as a getter if the first and only argument is not an object */
} else {
- v = this.node.getAttribute(a)
- return v == null ?
- SVG.defaults.attrs[a] :
- SVG.regex.test(v, 'isNumber') ?
- parseFloat(v) : v
- }
-
- } else if (a == 'style') {
- /* redirect to the style method */
- return this.style(v)
-
- } else {
- /* treat x differently on text elements */
- if (a == 'x' && Array.isArray(this.lines))
- for (n = this.lines.length - 1; n >= 0; n--)
- this.lines[n].attr(a, v)
-
- /* BUG FIX: some browsers will render a stroke if a color is given even though stroke width is 0 */
- if (a == 'stroke-width')
- this.attr('stroke', parseFloat(v) > 0 ? this._stroke : null)
- else if (a == 'stroke')
- this._stroke = v
-
- /* ensure full hex color */
- if (SVG.Color.test(v) || SVG.Color.isRgb(v))
- v = new SVG.Color(v)
-
- /* ensure correct numeric values */
- else if (typeof v === 'number')
- v = new SVG.Number(v)
-
- /* parse array values */
- else if (Array.isArray(v))
- v = new SVG.Array(v)
-
- /* set give attribute on node */
- n != null ?
- this.node.setAttributeNS(n, a, v.toString()) :
- this.node.setAttribute(a, v.toString())
-
- /* if the passed argument belongs in the style as well, add it there */
- if (this._isStyle(a)) {
- a == 'text' ?
- this.text(v) :
- a == 'leading' && this.leading ?
- this.leading(v) :
- this.style(a, v)
+ /* treat x differently on text elements */
+ if (a == 'x' && Array.isArray(this.lines))
+ for (n = this.lines.length - 1; n >= 0; n--)
+ this.lines[n].attr(a, v)
- /* rebuild if required */
- if (this.rebuild)
- this.rebuild(a, v)
+ /* BUG FIX: some browsers will render a stroke if a color is given even though stroke width is 0 */
+ if (a == 'stroke-width')
+ this.attr('stroke', parseFloat(v) > 0 ? this._stroke : null)
+ else if (a == 'stroke')
+ this._stroke = v
+
+ /* ensure full hex color */
+ if (SVG.Color.test(v) || SVG.Color.isRgb(v))
+ v = new SVG.Color(v)
+
+ /* ensure correct numeric values */
+ else if (typeof v === 'number')
+ v = new SVG.Number(v)
+
+ /* parse array values */
+ else if (Array.isArray(v))
+ v = new SVG.Array(v)
+
+ /* set give attribute on node */
+ n != null ?
+ this.node.setAttributeNS(n, a, v.toString()) :
+ this.node.setAttribute(a, v.toString())
+
+ /* if the passed argument belongs in the style as well, add it there */
+ if (this._isStyle(a)) {
+ a == 'text' ?
+ this.text(v) :
+ a == 'leading' && this.leading ?
+ this.leading(v) :
+ this.style(a, v)
+
+ /* rebuild if required */
+ if (this.rebuild)
+ this.rebuild(a, v)
+ }
}
+
+ return this
}
-
- return this
- }
- // Manage transformations
- , transform: function(o, v) {
-
- if (arguments.length == 0) {
- /* act as a getter if no argument is given */
- return this.trans
+ // Manage transformations
+ , transform: function(o, v) {
- } else if (typeof o === 'string') {
- /* act as a getter if only one string argument is given */
- if (arguments.length < 2)
- return this.trans[o]
+ if (arguments.length == 0) {
+ /* act as a getter if no argument is given */
+ return this.trans
+
+ } else if (typeof o === 'string') {
+ /* act as a getter if only one string argument is given */
+ if (arguments.length < 2)
+ return this.trans[o]
+
+ /* apply transformations as object if key value arguments are given*/
+ var transform = {}
+ transform[o] = v
+
+ return this.transform(transform)
+ }
- /* apply transformations as object if key value arguments are given*/
- var transform = {}
- transform[o] = v
+ /* ... otherwise continue as a setter */
+ var transform = []
+
+ /* parse matrix */
+ o = this._parseMatrix(o)
+
+ /* merge values */
+ for (v in o)
+ if (o[v] != null)
+ this.trans[v] = o[v]
+
+ /* compile matrix */
+ this.trans.matrix = this.trans.a
+ + ' ' + this.trans.b
+ + ' ' + this.trans.c
+ + ' ' + this.trans.d
+ + ' ' + this.trans.e
+ + ' ' + this.trans.f
+
+ /* alias current transformations */
+ o = this.trans
- return this.transform(transform)
+ /* add matrix */
+ if (o.matrix != SVG.defaults.matrix)
+ transform.push('matrix(' + o.matrix + ')')
+
+ /* add rotation */
+ if (o.rotation != 0)
+ transform.push('rotate(' + o.rotation + ' ' + (o.cx == null ? this.bbox().cx : o.cx) + ' ' + (o.cy == null ? this.bbox().cy : o.cy) + ')')
+
+ /* add scale */
+ if (o.scaleX != 1 || o.scaleY != 1)
+ transform.push('scale(' + o.scaleX + ' ' + o.scaleY + ')')
+
+ /* add skew on x axis */
+ if (o.skewX != 0)
+ transform.push('skewX(' + o.skewX + ')')
+
+ /* add skew on y axis */
+ if (o.skewY != 0)
+ transform.push('skewY(' + o.skewY + ')')
+
+ /* add translation */
+ if (o.x != 0 || o.y != 0)
+ transform.push('translate(' + new SVG.Number(o.x / o.scaleX) + ' ' + new SVG.Number(o.y / o.scaleY) + ')')
+
+ /* update transformations, even if there are none */
+ if (transform.length == 0)
+ this.node.removeAttribute('transform')
+ else
+ this.node.setAttribute('transform', transform.join(' '))
+
+ return this
}
-
- /* ... otherwise continue as a setter */
- var transform = []
-
- /* parse matrix */
- o = this._parseMatrix(o)
-
- /* merge values */
- for (v in o)
- if (o[v] != null)
- this.trans[v] = o[v]
-
- /* compile matrix */
- this.trans.matrix = this.trans.a
- + ' ' + this.trans.b
- + ' ' + this.trans.c
- + ' ' + this.trans.d
- + ' ' + this.trans.e
- + ' ' + this.trans.f
-
- /* alias current transformations */
- o = this.trans
-
- /* add matrix */
- if (o.matrix != SVG.defaults.matrix)
- transform.push('matrix(' + o.matrix + ')')
-
- /* add rotation */
- if (o.rotation != 0)
- transform.push('rotate(' + o.rotation + ' ' + (o.cx == null ? this.bbox().cx : o.cx) + ' ' + (o.cy == null ? this.bbox().cy : o.cy) + ')')
-
- /* add scale */
- if (o.scaleX != 1 || o.scaleY != 1)
- transform.push('scale(' + o.scaleX + ' ' + o.scaleY + ')')
-
- /* add skew on x axis */
- if (o.skewX != 0)
- transform.push('skewX(' + o.skewX + ')')
-
- /* add skew on y axis */
- if (o.skewY != 0)
- transform.push('skewY(' + o.skewY + ')')
-
- /* add translation */
- if (o.x != 0 || o.y != 0)
- transform.push('translate(' + new SVG.Number(o.x / o.scaleX) + ' ' + new SVG.Number(o.y / o.scaleY) + ')')
-
- /* update transformations, even if there are none */
- if (transform.length == 0)
- this.node.removeAttribute('transform')
- else
- this.node.setAttribute('transform', transform.join(' '))
-
- return this
- }
- // Dynamic style generator
- , style: function(s, v) {
- if (arguments.length == 0) {
- /* get full style */
- return this.attr('style') || ''
-
- } else if (arguments.length < 2) {
- /* apply every style individually if an object is passed */
- if (typeof s == 'object') {
- for (v in s) this.style(v, s[v])
+ // Dynamic style generator
+ , style: function(s, v) {
+ if (arguments.length == 0) {
+ /* get full style */
+ return this.attr('style') || ''
- } else if (SVG.regex.isCss.test(s)) {
- /* parse css string */
- s = s.split(';')
+ } else if (arguments.length < 2) {
+ /* apply every style individually if an object is passed */
+ if (typeof s == 'object') {
+ for (v in s) this.style(v, s[v])
+
+ } else if (SVG.regex.isCss.test(s)) {
+ /* parse css string */
+ s = s.split(';')
- /* apply every definition individually */
- for (var i = 0; i < s.length; i++) {
- v = s[i].split(':')
+ /* apply every definition individually */
+ for (var i = 0; i < s.length; i++) {
+ v = s[i].split(':')
- if (v.length == 2)
- this.style(v[0].replace(/\s+/g, ''), v[1].replace(/^\s+/,'').replace(/\s+$/,''))
+ if (v.length == 2)
+ this.style(v[0].replace(/\s+/g, ''), v[1].replace(/^\s+/,'').replace(/\s+$/,''))
+ }
+ } else {
+ /* act as a getter if the first and only argument is not an object */
+ return this.styles[s]
}
+
+ } else if (v === null || SVG.regex.test(v, 'isBlank')) {
+ /* remove value */
+ delete this.styles[s]
+
} else {
- /* act as a getter if the first and only argument is not an object */
- return this.styles[s]
+ /* store value */
+ this.styles[s] = v
}
-
- } else if (v === null || SVG.regex.test(v, 'isBlank')) {
- /* remove value */
- delete this.styles[s]
- } else {
- /* store value */
- this.styles[s] = v
+ /* rebuild style string */
+ s = ''
+ for (v in this.styles)
+ s += v + ':' + this.styles[v] + ';'
+
+ /* apply style */
+ if (s == '')
+ this.node.removeAttribute('style')
+ else
+ this.node.setAttribute('style', s)
+
+ return this
}
-
- /* rebuild style string */
- s = ''
- for (v in this.styles)
- s += v + ':' + this.styles[v] + ';'
-
- /* apply style */
- if (s == '')
- this.node.removeAttribute('style')
- else
- this.node.setAttribute('style', s)
-
- return this
- }
- // Get bounding box
- , bbox: function() {
- return new SVG.BBox(this)
- }
- // Get rect box
- , rbox: function() {
- return new SVG.RBox(this)
- }
- // Checks whether the given point inside the bounding box of the element
- , inside: function(x, y) {
- var box = this.bbox()
-
- return x > box.x
- && y > box.y
- && x < box.x + box.width
- && y < box.y + box.height
- }
- // Show element
- , show: function() {
- return this.style('display', '')
- }
- // Hide element
- , hide: function() {
- return this.style('display', 'none')
- }
- // Is element visible?
- , visible: function() {
- return this.style('display') != 'none'
- }
- // Return id on string conversion
- , toString: function() {
- return this.attr('id')
- }
- // Private: find svg parent by instance
- , _parent: function(parent) {
- var element = this
-
- while (element != null && !(element instanceof parent))
- element = element.parent
-
- return element
- }
- // Private: tester method for style detection
- , _isStyle: function(a) {
- return typeof a == 'string' ? SVG.regex.test(a, 'isStyle') : false
- }
- // Private: parse a matrix string
- , _parseMatrix: function(o) {
- if (o.matrix) {
- /* split matrix string */
- var m = o.matrix.replace(/\s/g, '').split(',')
-
- /* pasrse values */
- if (m.length == 6) {
- o.a = parseFloat(m[0])
- o.b = parseFloat(m[1])
- o.c = parseFloat(m[2])
- o.d = parseFloat(m[3])
- o.e = parseFloat(m[4])
- o.f = parseFloat(m[5])
- }
+ // Get bounding box
+ , bbox: function() {
+ return new SVG.BBox(this)
}
-
- return o
- }
- // Private: calculate proportional width and height values when necessary
- , _proportionalSize: function(width, height) {
- if (width == null || height == null) {
+ // Get rect box
+ , rbox: function() {
+ return new SVG.RBox(this)
+ }
+ // Checks whether the given point inside the bounding box of the element
+ , inside: function(x, y) {
var box = this.bbox()
+
+ return x > box.x
+ && y > box.y
+ && x < box.x + box.width
+ && y < box.y + box.height
+ }
+ // Show element
+ , show: function() {
+ return this.style('display', '')
+ }
+ // Hide element
+ , hide: function() {
+ return this.style('display', 'none')
+ }
+ // Is element visible?
+ , visible: function() {
+ return this.style('display') != 'none'
+ }
+ // Return id on string conversion
+ , toString: function() {
+ return this.attr('id')
+ }
+ // Private: find svg parent by instance
+ , _parent: function(parent) {
+ var element = this
+
+ while (element != null && !(element instanceof parent))
+ element = element.parent
- if (height == null)
- height = box.height / box.width * width
- else if (width == null)
- width = box.width / box.height * height
+ return element
}
-
- return {
- width: width
- , height: height
+ // Private: tester method for style detection
+ , _isStyle: function(a) {
+ return typeof a == 'string' ? SVG.regex.test(a, 'isStyle') : false
+ }
+ // Private: parse a matrix string
+ , _parseMatrix: function(o) {
+ if (o.matrix) {
+ /* split matrix string */
+ var m = o.matrix.replace(/\s/g, '').split(',')
+
+ /* pasrse values */
+ if (m.length == 6) {
+ o.a = parseFloat(m[0])
+ o.b = parseFloat(m[1])
+ o.c = parseFloat(m[2])
+ o.d = parseFloat(m[3])
+ o.e = parseFloat(m[4])
+ o.f = parseFloat(m[5])
+ }
+ }
+
+ return o
+ }
+ // Private: calculate proportional width and height values when necessary
+ , _proportionalSize: function(width, height) {
+ if (width == null || height == null) {
+ var box = this.bbox()
+
+ if (height == null)
+ height = box.height / box.width * width
+ else if (width == null)
+ width = box.width / box.height * height
+ }
+
+ return {
+ width: width
+ , height: height
+ }
}
}
})
- SVG.Parent = function(element) {
- this.constructor.call(this, element)
- }
+ SVG.Parent = SVG.invent({
+ // Initialize node
+ create: function(element) {
+ this.constructor.call(this, element)
+ }
- // Inherit from SVG.Element
- SVG.Parent.prototype = new SVG.Element
+ // Inherit from
+ , inherit: SVG.Element
- //
- SVG.extend(SVG.Parent, {
- // Returns all child elements
- children: function() {
- return this._children || (this._children = [])
- }
- // Add given element at a position
- , add: function(element, i) {
- if (!this.has(element)) {
- /* define insertion index if none given */
- i = i == null ? this.children().length : i
-
- /* remove references from previous parent */
- if (element.parent)
- element.parent.children().splice(element.parent.index(element), 1)
-
- /* add element references */
- this.children().splice(i, 0, element)
- this.node.insertBefore(element.node, this.node.childNodes[i] || null)
- element.parent = this
+ // Add class methods
+ , extend: {
+ // Returns all child elements
+ children: function() {
+ return this._children || (this._children = [])
}
+ // Add given element at a position
+ , add: function(element, i) {
+ if (!this.has(element)) {
+ /* define insertion index if none given */
+ i = i == null ? this.children().length : i
+
+ /* remove references from previous parent */
+ if (element.parent)
+ element.parent.children().splice(element.parent.index(element), 1)
+
+ /* add element references */
+ this.children().splice(i, 0, element)
+ this.node.insertBefore(element.node, this.node.childNodes[i] || null)
+ element.parent = this
+ }
- /* reposition defs */
- if (this._defs) {
- this.node.removeChild(this._defs.node)
- this.node.appendChild(this._defs.node)
+ /* reposition defs */
+ if (this._defs) {
+ this.node.removeChild(this._defs.node)
+ this.node.appendChild(this._defs.node)
+ }
+
+ return this
}
-
- return this
- }
- // Basically does the same as `add()` but returns the added element instead
- , put: function(element, i) {
- this.add(element, i)
- return element
- }
- // Checks if the given element is a child
- , has: function(element) {
- return this.index(element) >= 0
- }
- // Gets index of given element
- , index: function(element) {
- return this.children().indexOf(element)
- }
- // Get a element at the given index
- , get: function(i) {
- return this.children()[i]
- }
- // Get first child, skipping the defs node
- , first: function() {
- return this.children()[0]
- }
- // Get the last child
- , last: function() {
- return this.children()[this.children().length - 1]
- }
- // Iterates over all children and invokes a given block
- , each: function(block, deep) {
- var i, il
- , children = this.children()
-
- for (i = 0, il = children.length; i < il; i++) {
- if (children[i] instanceof SVG.Element)
- block.apply(children[i], [i, children])
-
- if (deep && (children[i] instanceof SVG.Container))
- children[i].each(block, deep)
+ // Basically does the same as `add()` but returns the added element instead
+ , put: function(element, i) {
+ this.add(element, i)
+ return element
}
-
- return this
- }
- // Remove a child element at a position
- , removeElement: function(element) {
- this.children().splice(this.index(element), 1)
- this.node.removeChild(element.node)
- element.parent = null
+ // Checks if the given element is a child
+ , has: function(element) {
+ return this.index(element) >= 0
+ }
+ // Gets index of given element
+ , index: function(element) {
+ return this.children().indexOf(element)
+ }
+ // Get a element at the given index
+ , get: function(i) {
+ return this.children()[i]
+ }
+ // Get first child, skipping the defs node
+ , first: function() {
+ return this.children()[0]
+ }
+ // Get the last child
+ , last: function() {
+ return this.children()[this.children().length - 1]
+ }
+ // Iterates over all children and invokes a given block
+ , each: function(block, deep) {
+ var i, il
+ , children = this.children()
+
+ for (i = 0, il = children.length; i < il; i++) {
+ if (children[i] instanceof SVG.Element)
+ block.apply(children[i], [i, children])
+
+ if (deep && (children[i] instanceof SVG.Container))
+ children[i].each(block, deep)
+ }
- return this
- }
- // Remove all elements in this container
- , clear: function() {
- /* remove children */
- for (var i = this.children().length - 1; i >= 0; i--)
- this.removeElement(this.children()[i])
+ return this
+ }
+ // Remove a child element at a position
+ , removeElement: function(element) {
+ this.children().splice(this.index(element), 1)
+ this.node.removeChild(element.node)
+ element.parent = null
+
+ return this
+ }
+ // Remove all elements in this container
+ , clear: function() {
+ /* remove children */
+ for (var i = this.children().length - 1; i >= 0; i--)
+ this.removeElement(this.children()[i])
- /* remove defs node */
- if (this._defs)
- this._defs.clear()
+ /* remove defs node */
+ if (this._defs)
+ this._defs.clear()
- return this
- }
- , // Get defs
- defs: function() {
- return this.doc().defs()
+ return this
+ }
+ , // Get defs
+ defs: function() {
+ return this.doc().defs()
+ }
}
+
})
- SVG.Container = function(element) {
- this.constructor.call(this, element)
- }
-
- // Inherit from SVG.Parent
- SVG.Container.prototype = new SVG.Parent
-
- //
- SVG.extend(SVG.Container, {
- // Get the viewBox and calculate the zoom value
- viewbox: function(v) {
- if (arguments.length == 0)
- /* act as a getter if there are no arguments */
- return new SVG.ViewBox(this)
-
- /* otherwise act as a setter */
- v = arguments.length == 1 ?
- [v.x, v.y, v.width, v.height] :
- [].slice.call(arguments)
-
- return this.attr('viewBox', v)
+
+ SVG.Container = SVG.invent({
+ // Initialize node
+ create: function(element) {
+ this.constructor.call(this, element)
+ }
+
+ // Inherit from
+ , inherit: SVG.Parent
+
+ // Add class methods
+ , extend: {
+ // Get the viewBox and calculate the zoom value
+ viewbox: function(v) {
+ if (arguments.length == 0)
+ /* act as a getter if there are no arguments */
+ return new SVG.ViewBox(this)
+
+ /* otherwise act as a setter */
+ v = arguments.length == 1 ?
+ [v.x, v.y, v.width, v.height] :
+ [].slice.call(arguments)
+
+ return this.attr('viewBox', v)
+ }
}
})
@@ -2125,48 +2162,48 @@
}
})
- SVG.Defs = function() {
- this.constructor.call(this, SVG.create('defs'))
- }
+ SVG.Defs = SVG.invent({
+ // Initialize node
+ create: 'defs'
- // Inherits from SVG.Container
- SVG.Defs.prototype = new SVG.Container
+ // Inherit from
+ , inherit: SVG.Container
+ })
- SVG.G = function() {
- this.constructor.call(this, SVG.create('g'))
- }
-
- // Inherit from SVG.Container
- SVG.G.prototype = new SVG.Container
-
- //
- SVG.extend(SVG.G, {
- // Move over x-axis
- x: function(x) {
- return x == null ? this.trans.x : this.transform('x', x)
- }
- // Move over y-axis
- , y: function(y) {
- return y == null ? this.trans.y : this.transform('y', y)
- }
- // Move by center over x-axis
- , cx: function(x) {
- return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2)
- }
- // Move by center over y-axis
- , cy: function(y) {
- return y == null ? this.bbox().cy : this.y(y - this.bbox().height / 2)
+ SVG.G = SVG.invent({
+ // Initialize node
+ create: 'g'
+
+ // Inherit from
+ , inherit: SVG.Container
+
+ // Add class methods
+ , extend: {
+ // Move over x-axis
+ x: function(x) {
+ return x == null ? this.trans.x : this.transform('x', x)
+ }
+ // Move over y-axis
+ , y: function(y) {
+ return y == null ? this.trans.y : this.transform('y', y)
+ }
+ // Move by center over x-axis
+ , cx: function(x) {
+ return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2)
+ }
+ // Move by center over y-axis
+ , cy: function(y) {
+ return y == null ? this.bbox().cy : this.y(y - this.bbox().height / 2)
+ }
}
- })
-
- //
- SVG.extend(SVG.Container, {
- // Create a group element
- group: function() {
- return this.put(new SVG.G)
+ // Add parent method
+ , construct: {
+ // Create a group element
+ group: function() {
+ return this.put(new SVG.G)
+ }
}
-
})
SVG.extend(SVG.Element, {
@@ -2234,34 +2271,45 @@
})
- SVG.Mask = function() {
- this.constructor.call(this, SVG.create('mask'))
+ SVG.Mask = SVG.invent({
+ // Initialize node
+ create: function() {
+ this.constructor.call(this, SVG.create('mask'))
- /* keep references to masked elements */
- this.targets = []
- }
+ /* keep references to masked elements */
+ this.targets = []
+ }
- // Inherit from SVG.Container
- SVG.Mask.prototype = new SVG.Container
+ // Inherit from
+ , inherit: SVG.Container
- //
- SVG.extend(SVG.Mask, {
- // Unmask all masked elements and remove itself
- remove: function() {
- /* unmask all targets */
- for (var i = this.targets.length - 1; i >= 0; i--)
- if (this.targets[i])
- this.targets[i].unmask()
- delete this.targets
-
- /* remove mask from parent */
- this.parent.removeElement(this)
-
- return this
+ // Add class methods
+ , extend: {
+ // Unmask all masked elements and remove itself
+ remove: function() {
+ /* unmask all targets */
+ for (var i = this.targets.length - 1; i >= 0; i--)
+ if (this.targets[i])
+ this.targets[i].unmask()
+ delete this.targets
+
+ /* remove mask from parent */
+ this.parent.removeElement(this)
+
+ return this
+ }
+ }
+
+ // Add parent method
+ , construct: {
+ // Create masking element
+ mask: function() {
+ return this.defs().put(new SVG.Mask)
+ }
}
})
- //
+
SVG.extend(SVG.Element, {
// Distribute mask to svg element
maskWith: function(element) {
@@ -2281,40 +2329,43 @@
}
})
+
+
+ SVG.Clip = SVG.invent({
+ // Initialize node
+ create: function() {
+ this.constructor.call(this, SVG.create('clipPath'))
- //
- SVG.extend(SVG.Container, {
- // Create masking element
- mask: function() {
- return this.defs().put(new SVG.Mask)
+ /* keep references to clipped elements */
+ this.targets = []
}
-
- })
-
- SVG.Clip = function() {
- this.constructor.call(this, SVG.create('clipPath'))
- /* keep references to clipped elements */
- this.targets = []
- }
+ // Inherit from
+ , inherit: SVG.Container
- // Inherit from SVG.Container
- SVG.Clip.prototype = new SVG.Container
+ // Add class methods
+ , extend: {
+ // Unclip all clipped elements and remove itself
+ remove: function() {
+ /* unclip all targets */
+ for (var i = this.targets.length - 1; i >= 0; i--)
+ if (this.targets[i])
+ this.targets[i].unclip()
+ delete this.targets
- //
- SVG.extend(SVG.Clip, {
- // Unclip all clipped elements and remove itself
- remove: function() {
- /* unclip all targets */
- for (var i = this.targets.length - 1; i >= 0; i--)
- if (this.targets[i])
- this.targets[i].unclip()
- delete this.targets
-
- /* remove clipPath from parent */
- this.parent.removeElement(this)
-
- return this
+ /* remove clipPath from parent */
+ this.parent.removeElement(this)
+
+ return this
+ }
+ }
+
+ // Add parent method
+ , construct: {
+ // Create clipping element
+ clip: function() {
+ return this.defs().put(new SVG.Clip)
+ }
}
})
@@ -2338,72 +2389,72 @@
}
})
-
- //
- SVG.extend(SVG.Container, {
- // Create clipping element
- clip: function() {
- return this.defs().put(new SVG.Clip)
- }
-
- })
- SVG.Gradient = function(type) {
- this.constructor.call(this, SVG.create(type + 'Gradient'))
-
- /* store type */
- this.type = type
- }
-
- // Inherit from SVG.Container
- SVG.Gradient.prototype = new SVG.Container
-
- //
- SVG.extend(SVG.Gradient, {
- // From position
- from: function(x, y) {
- return this.type == 'radial' ?
- this.attr({ fx: new SVG.Number(x), fy: new SVG.Number(y) }) :
- this.attr({ x1: new SVG.Number(x), y1: new SVG.Number(y) })
- }
- // To position
- , to: function(x, y) {
- return this.type == 'radial' ?
- this.attr({ cx: new SVG.Number(x), cy: new SVG.Number(y) }) :
- this.attr({ x2: new SVG.Number(x), y2: new SVG.Number(y) })
- }
- // Radius for radial gradient
- , radius: function(r) {
- return this.type == 'radial' ?
- this.attr({ r: new SVG.Number(r) }) :
- this
- }
- // Add a color stop
- , at: function(stop) {
- return this.put(new SVG.Stop(stop))
- }
- // Update gradient
- , update: function(block) {
- /* remove all stops */
- this.clear()
-
- /* invoke passed block */
- block(this)
+ SVG.Gradient = SVG.invent({
+ // Initialize node
+ create: function(type) {
+ this.constructor.call(this, SVG.create(type + 'Gradient'))
- return this
- }
- // Return the fill id
- , fill: function() {
- return 'url(#' + this.attr('id') + ')'
+ /* store type */
+ this.type = type
}
- // Alias string convertion to fill
- , toString: function() {
- return this.fill()
+
+ // Inherit from
+ , inherit: SVG.Container
+
+ // Add class methods
+ , extend: {
+ // From position
+ from: function(x, y) {
+ return this.type == 'radial' ?
+ this.attr({ fx: new SVG.Number(x), fy: new SVG.Number(y) }) :
+ this.attr({ x1: new SVG.Number(x), y1: new SVG.Number(y) })
+ }
+ // To position
+ , to: function(x, y) {
+ return this.type == 'radial' ?
+ this.attr({ cx: new SVG.Number(x), cy: new SVG.Number(y) }) :
+ this.attr({ x2: new SVG.Number(x), y2: new SVG.Number(y) })
+ }
+ // Radius for radial gradient
+ , radius: function(r) {
+ return this.type == 'radial' ?
+ this.attr({ r: new SVG.Number(r) }) :
+ this
+ }
+ // Add a color stop
+ , at: function(stop) {
+ return this.put(new SVG.Stop().update(stop))
+ }
+ // Update gradient
+ , update: function(block) {
+ /* remove all stops */
+ this.clear()
+
+ /* invoke passed block */
+ block(this)
+
+ return this
+ }
+ // Return the fill id
+ , fill: function() {
+ return 'url(#' + this.attr('id') + ')'
+ }
+ // Alias string convertion to fill
+ , toString: function() {
+ return this.fill()
+ }
}
+ // Add parent method
+ , construct: {
+ // Create gradient element in defs
+ gradient: function(type, block) {
+ return this.defs().gradient(type, block)
+ }
+ }
})
- //
SVG.extend(SVG.Defs, {
// define gradient
gradient: function(type, block) {
@@ -2417,356 +2468,367 @@
})
- //
- SVG.extend(SVG.Container, {
- // Create gradient element in defs
- gradient: function(type, block) {
- return this.defs().gradient(type, block)
- }
-
- })
+ SVG.Stop = SVG.invent({
+ // Initialize node
+ create: 'stop'
+ // Inherit from
+ , inherit: SVG.Element
- SVG.Stop = function(stop) {
- this.constructor.call(this, SVG.create('stop'))
-
- /* immediatelly build stop */
- this.update(stop)
- }
-
- // Inherit from SVG.Element
- SVG.Stop.prototype = new SVG.Element
-
- //
- SVG.extend(SVG.Stop, {
- // add color stops
- update: function(o) {
- /* set attributes */
- if (o.opacity != null) this.attr('stop-opacity', o.opacity)
- if (o.color != null) this.attr('stop-color', o.color)
- if (o.offset != null) this.attr('offset', new SVG.Number(o.offset))
+ // Add class methods
+ , extend: {
+ // add color stops
+ update: function(o) {
+ /* set attributes */
+ if (o.opacity != null) this.attr('stop-opacity', o.opacity)
+ if (o.color != null) this.attr('stop-color', o.color)
+ if (o.offset != null) this.attr('offset', new SVG.Number(o.offset))
- return this
+ return this
+ }
}
-
- })
+ })
- SVG.Doc = function(element) {
- /* ensure the presence of a html element */
- this.parent = typeof element == 'string' ?
- document.getElementById(element) :
- element
-
- /* If the target is an svg element, use that element as the main wrapper.
- This allows svg.js to work with svg documents as well. */
- this.constructor
- .call(this, this.parent.nodeName == 'svg' ? this.parent : SVG.create('svg'))
-
- /* set svg element attributes */
- this
- .attr({ xmlns: SVG.ns, version: '1.1', width: '100%', height: '100%' })
- .attr('xmlns:xlink', SVG.xlink, SVG.xmlns)
-
- /* create the <defs> node */
- this._defs = new SVG.Defs
- this._defs.parent = this
- this.node.appendChild(this._defs.node)
-
- /* turno of sub pixel offset by default */
- this.doSubPixelOffsetFix = false
-
- /* ensure correct rendering */
- if (this.parent.nodeName != 'svg')
- this.stage()
- }
-
- // Inherits from SVG.Container
- SVG.Doc.prototype = new SVG.Container
-
- //
- SVG.extend(SVG.Doc, {
- // Hack for safari preventing text to be rendered in one line.
- // Basically it sets the position of the svg node to absolute
- // when the dom is loaded, and resets it to relative a few milliseconds later.
- // It also handles sub-pixel offset rendering properly.
- stage: function() {
- var check
- , element = this
- , wrapper = document.createElement('div')
-
- /* set temporary wrapper to position relative */
- wrapper.style.cssText = 'position:relative;height:100%;'
-
- /* put element into wrapper */
- element.parent.appendChild(wrapper)
- wrapper.appendChild(element.node)
-
- /* check for dom:ready */
- check = function() {
- if (document.readyState === 'complete') {
- element.style('position:absolute;')
- setTimeout(function() {
- /* set position back to relative */
- element.style('position:relative;overflow:hidden;')
-
- /* remove temporary wrapper */
- element.parent.removeChild(element.node.parentNode)
- element.node.parentNode.removeChild(element.node)
- element.parent.appendChild(element.node)
-
- /* after wrapping is done, fix sub-pixel offset */
- element.subPixelOffsetFix()
-
- /* make sure sub-pixel offset is fixed every time the window is resized */
- SVG.on(window, 'resize', function() {
+ SVG.Doc = SVG.invent({
+ // Initialize node
+ create: function(element) {
+ /* ensure the presence of a html element */
+ this.parent = typeof element == 'string' ?
+ document.getElementById(element) :
+ element
+
+ /* If the target is an svg element, use that element as the main wrapper.
+ This allows svg.js to work with svg documents as well. */
+ this.constructor
+ .call(this, this.parent.nodeName == 'svg' ? this.parent : SVG.create('svg'))
+
+ /* set svg element attributes */
+ this
+ .attr({ xmlns: SVG.ns, version: '1.1', width: '100%', height: '100%' })
+ .attr('xmlns:xlink', SVG.xlink, SVG.xmlns)
+
+ /* create the <defs> node */
+ this._defs = new SVG.Defs
+ this._defs.parent = this
+ this.node.appendChild(this._defs.node)
+
+ /* turno of sub pixel offset by default */
+ this.doSubPixelOffsetFix = false
+
+ /* ensure correct rendering */
+ if (this.parent.nodeName != 'svg')
+ this.stage()
+ }
+
+ // Inherit from
+ , inherit: SVG.Container
+
+ // Add class methods
+ , extend: {
+ // Hack for safari preventing text to be rendered in one line.
+ // Basically it sets the position of the svg node to absolute
+ // when the dom is loaded, and resets it to relative a few milliseconds later.
+ // It also handles sub-pixel offset rendering properly.
+ stage: function() {
+ var check
+ , element = this
+ , wrapper = document.createElement('div')
+
+ /* set temporary wrapper to position relative */
+ wrapper.style.cssText = 'position:relative;height:100%;'
+
+ /* put element into wrapper */
+ element.parent.appendChild(wrapper)
+ wrapper.appendChild(element.node)
+
+ /* check for dom:ready */
+ check = function() {
+ if (document.readyState === 'complete') {
+ element.style('position:absolute;')
+ setTimeout(function() {
+ /* set position back to relative */
+ element.style('position:relative;overflow:hidden;')
+
+ /* remove temporary wrapper */
+ element.parent.removeChild(element.node.parentNode)
+ element.node.parentNode.removeChild(element.node)
+ element.parent.appendChild(element.node)
+
+ /* after wrapping is done, fix sub-pixel offset */
element.subPixelOffsetFix()
- })
-
- }, 5)
- } else {
- setTimeout(check, 10)
+
+ /* make sure sub-pixel offset is fixed every time the window is resized */
+ SVG.on(window, 'resize', function() {
+ element.subPixelOffsetFix()
+ })
+
+ }, 5)
+ } else {
+ setTimeout(check, 10)
+ }
}
- }
- check()
+ check()
- return this
- }
+ return this
+ }
- // Creates and returns defs element
- , defs: function() {
- return this._defs
- }
+ // Creates and returns defs element
+ , defs: function() {
+ return this._defs
+ }
- // Fix for possible sub-pixel offset. See:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=608812
- , subPixelOffsetFix: function() {
- if (this.doSubPixelOffsetFix) {
- var pos = this.node.getScreenCTM()
+ // Fix for possible sub-pixel offset. See:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=608812
+ , subPixelOffsetFix: function() {
+ if (this.doSubPixelOffsetFix) {
+ var pos = this.node.getScreenCTM()
+
+ if (pos)
+ this
+ .style('left', (-pos.e % 1) + 'px')
+ .style('top', (-pos.f % 1) + 'px')
+ }
- if (pos)
- this
- .style('left', (-pos.e % 1) + 'px')
- .style('top', (-pos.f % 1) + 'px')
+ return this
}
-
- return this
- }
- , fixSubPixelOffset: function() {
- this.doSubPixelOffsetFix = true
+ , fixSubPixelOffset: function() {
+ this.doSubPixelOffsetFix = true
- return this
+ return this
+ }
}
})
- SVG.Shape = function(element) {
- this.constructor.call(this, element)
- }
-
- // Inherit from SVG.Element
- SVG.Shape.prototype = new SVG.Element
- SVG.Use = function() {
- this.constructor.call(this, SVG.create('use'))
- }
-
- // Inherit from SVG.Shape
- SVG.Use.prototype = new SVG.Shape
+ SVG.Shape = SVG.invent({
+ // Initialize node
+ create: function(element) {
+ this.constructor.call(this, element)
+ }
- //
- SVG.extend(SVG.Use, {
- // Use element as a reference
- element: function(element) {
- /* store target element */
- this.target = element
+ // Inherit from
+ , inherit: SVG.Element
- /* set lined element */
- return this.attr('href', '#' + element, SVG.xlink)
+ })
+
+ SVG.Use = SVG.invent({
+ // Initialize node
+ create: 'use'
+
+ // Inherit from
+ , inherit: SVG.Shape
+
+ // Add class methods
+ , extend: {
+ // Use element as a reference
+ element: function(element) {
+ /* store target element */
+ this.target = element
+
+ /* set lined element */
+ return this.attr('href', '#' + element, SVG.xlink)
+ }
}
- })
-
- //
- SVG.extend(SVG.Container, {
- // Create a use element
- use: function(element) {
- return this.put(new SVG.Use).element(element)
+ // Add parent method
+ , construct: {
+ // Create a use element
+ use: function(element) {
+ return this.put(new SVG.Use).element(element)
+ }
}
-
})
- SVG.Rect = function() {
- this.constructor.call(this, SVG.create('rect'))
- }
-
- // Inherit from SVG.Shape
- SVG.Rect.prototype = new SVG.Shape
-
- //
- SVG.extend(SVG.Container, {
- // Create a rect element
- rect: function(width, height) {
- return this.put(new SVG.Rect().size(width, height))
- }
-
+ SVG.Rect = SVG.invent({
+ // Initialize node
+ create: 'rect'
+
+ // Inherit from
+ , inherit: SVG.Shape
+
+ // Add parent method
+ , construct: {
+ // Create a rect element
+ rect: function(width, height) {
+ return this.put(new SVG.Rect().size(width, height))
+ }
+
+ }
+
})
- SVG.Ellipse = function() {
- this.constructor.call(this, SVG.create('ellipse'))
- }
-
- // Inherit from SVG.Shape
- SVG.Ellipse.prototype = new SVG.Shape
+ SVG.Ellipse = SVG.invent({
+ // Initialize node
+ create: 'ellipse'
+
+ // Inherit from
+ , inherit: SVG.Shape
+
+ // Add class methods
+ , extend: {
+ // Move over x-axis
+ x: function(x) {
+ return x == null ? this.cx() - this.attr('rx') : this.cx(x + this.attr('rx'))
+ }
+ // Move over y-axis
+ , y: function(y) {
+ return y == null ? this.cy() - this.attr('ry') : this.cy(y + this.attr('ry'))
+ }
+ // Move by center over x-axis
+ , cx: function(x) {
+ return x == null ? this.attr('cx') : this.attr('cx', new SVG.Number(x).divide(this.trans.scaleX))
+ }
+ // Move by center over y-axis
+ , cy: function(y) {
+ return y == null ? this.attr('cy') : this.attr('cy', new SVG.Number(y).divide(this.trans.scaleY))
+ }
+ // Set width of element
+ , width: function(width) {
+ return width == null ? this.attr('rx') * 2 : this.attr('rx', new SVG.Number(width).divide(2))
+ }
+ // Set height of element
+ , height: function(height) {
+ return height == null ? this.attr('ry') * 2 : this.attr('ry', new SVG.Number(height).divide(2))
+ }
+ // Custom size function
+ , size: function(width, height) {
+ var p = this._proportionalSize(width, height)
- //
- SVG.extend(SVG.Ellipse, {
- // Move over x-axis
- x: function(x) {
- return x == null ? this.cx() - this.attr('rx') : this.cx(x + this.attr('rx'))
- }
- // Move over y-axis
- , y: function(y) {
- return y == null ? this.cy() - this.attr('ry') : this.cy(y + this.attr('ry'))
- }
- // Move by center over x-axis
- , cx: function(x) {
- return x == null ? this.attr('cx') : this.attr('cx', new SVG.Number(x).divide(this.trans.scaleX))
- }
- // Move by center over y-axis
- , cy: function(y) {
- return y == null ? this.attr('cy') : this.attr('cy', new SVG.Number(y).divide(this.trans.scaleY))
- }
- // Set width of element
- , width: function(width) {
- return width == null ? this.attr('rx') * 2 : this.attr('rx', new SVG.Number(width).divide(2))
- }
- // Set height of element
- , height: function(height) {
- return height == null ? this.attr('ry') * 2 : this.attr('ry', new SVG.Number(height).divide(2))
+ return this.attr({
+ rx: new SVG.Number(p.width).divide(2)
+ , ry: new SVG.Number(p.height).divide(2)
+ })
+ }
+
}
- // Custom size function
- , size: function(width, height) {
- var p = this._proportionalSize(width, height)
- return this.attr({
- rx: new SVG.Number(p.width).divide(2)
- , ry: new SVG.Number(p.height).divide(2)
- })
+ // Add parent method
+ , construct: {
+ // Create circle element, based on ellipse
+ circle: function(size) {
+ return this.ellipse(size, size)
+ }
+ // Create an ellipse
+ , ellipse: function(width, height) {
+ return this.put(new SVG.Ellipse).size(width, height).move(0, 0)
+ }
+
}
-
- })
- //
- SVG.extend(SVG.Container, {
- // Create circle element, based on ellipse
- circle: function(size) {
- return this.ellipse(size, size)
- }
- // Create an ellipse
- , ellipse: function(width, height) {
- return this.put(new SVG.Ellipse).size(width, height).move(0, 0)
- }
-
})
-
- // Usage:
-
- // draw.ellipse(200, 100)
- SVG.Line = function() {
- this.constructor.call(this, SVG.create('line'))
- }
-
- // Inherit from SVG.Shape
- SVG.Line.prototype = new SVG.Shape
-
- // Add required methods
- SVG.extend(SVG.Line, {
- // Move over x-axis
- x: function(x) {
- var b = this.bbox()
-
- return x == null ? b.x : this.attr({
- x1: this.attr('x1') - b.x + x
- , x2: this.attr('x2') - b.x + x
- })
- }
- // Move over y-axis
- , y: function(y) {
- var b = this.bbox()
-
- return y == null ? b.y : this.attr({
- y1: this.attr('y1') - b.y + y
- , y2: this.attr('y2') - b.y + y
- })
- }
- // Move by center over x-axis
- , cx: function(x) {
- var half = this.bbox().width / 2
- return x == null ? this.x() + half : this.x(x - half)
- }
- // Move by center over y-axis
- , cy: function(y) {
- var half = this.bbox().height / 2
- return y == null ? this.y() + half : this.y(y - half)
- }
- // Set width of element
- , width: function(width) {
- var b = this.bbox()
+ SVG.Line = SVG.invent({
+ // Initialize node
+ create: 'line'
+
+ // Inherit from
+ , inherit: SVG.Shape
+
+ // Add class methods
+ , extend: {
+ // Move over x-axis
+ x: function(x) {
+ var b = this.bbox()
+
+ return x == null ? b.x : this.attr({
+ x1: this.attr('x1') - b.x + x
+ , x2: this.attr('x2') - b.x + x
+ })
+ }
+ // Move over y-axis
+ , y: function(y) {
+ var b = this.bbox()
+
+ return y == null ? b.y : this.attr({
+ y1: this.attr('y1') - b.y + y
+ , y2: this.attr('y2') - b.y + y
+ })
+ }
+ // Move by center over x-axis
+ , cx: function(x) {
+ var half = this.bbox().width / 2
+ return x == null ? this.x() + half : this.x(x - half)
+ }
+ // Move by center over y-axis
+ , cy: function(y) {
+ var half = this.bbox().height / 2
+ return y == null ? this.y() + half : this.y(y - half)
+ }
+ // Set width of element
+ , width: function(width) {
+ var b = this.bbox()
- return width == null ? b.width : this.attr(this.attr('x1') < this.attr('x2') ? 'x2' : 'x1', b.x + width)
- }
- // Set height of element
- , height: function(height) {
- var b = this.bbox()
+ return width == null ? b.width : this.attr(this.attr('x1') < this.attr('x2') ? 'x2' : 'x1', b.x + width)
+ }
+ // Set height of element
+ , height: function(height) {
+ var b = this.bbox()
- return height == null ? b.height : this.attr(this.attr('y1') < this.attr('y2') ? 'y2' : 'y1', b.y + height)
- }
- // Set line size by width and height
- , size: function(width, height) {
- var p = this._proportionalSize(width, height)
+ return height == null ? b.height : this.attr(this.attr('y1') < this.attr('y2') ? 'y2' : 'y1', b.y + height)
+ }
+ // Set line size by width and height
+ , size: function(width, height) {
+ var p = this._proportionalSize(width, height)
- return this.width(p.width).height(p.height)
- }
- // Set path data
- , plot: function(x1, y1, x2, y2) {
- return this.attr({
- x1: x1
- , y1: y1
- , x2: x2
- , y2: y2
- })
+ return this.width(p.width).height(p.height)
+ }
+ // Set path data
+ , plot: function(x1, y1, x2, y2) {
+ return this.attr({
+ x1: x1
+ , y1: y1
+ , x2: x2
+ , y2: y2
+ })
+ }
}
- })
-
- //
- SVG.extend(SVG.Container, {
- // Create a line element
- line: function(x1, y1, x2, y2) {
- return this.put(new SVG.Line().plot(x1, y1, x2, y2))
+ // Add parent method
+ , construct: {
+ // Create a line element
+ line: function(x1, y1, x2, y2) {
+ return this.put(new SVG.Line().plot(x1, y1, x2, y2))
+ }
}
-
})
- SVG.Polyline = function() {
- this.constructor.call(this, SVG.create('polyline'))
- }
-
- // Inherit from SVG.Shape
- SVG.Polyline.prototype = new SVG.Shape
+ SVG.Polyline = SVG.invent({
+ // Initialize node
+ create: 'polyline'
+
+ // Inherit from
+ , inherit: SVG.Shape
+
+ // Add parent method
+ , construct: {
+ // Create a wrapped polyline element
+ polyline: function(p) {
+ return this.put(new SVG.Polyline).plot(p)
+ }
+ }
+ })
- SVG.Polygon = function() {
- this.constructor.call(this, SVG.create('polygon'))
- }
+ SVG.Polygon = SVG.invent({
+ // Initialize node
+ create: 'polygon'
- // Inherit from SVG.Shape
- SVG.Polygon.prototype = new SVG.Shape
+ // Inherit from
+ , inherit: SVG.Shape
+
+ // Add parent method
+ , construct: {
+ // Create a wrapped polygon element
+ polygon: function(p) {
+ return this.put(new SVG.Polygon).plot(p)
+ }
+ }
+ })
// Add polygon-specific functions
SVG.extend(SVG.Polyline, SVG.Polygon, {
@@ -2808,397 +2870,389 @@
}
})
-
- //
- SVG.extend(SVG.Container, {
- // Create a wrapped polyline element
- polyline: function(p) {
- return this.put(new SVG.Polyline).plot(p)
- }
- // Create a wrapped polygon element
- , polygon: function(p) {
- return this.put(new SVG.Polygon).plot(p)
- }
-
- })
- SVG.Path = function() {
- this.constructor.call(this, SVG.create('path'))
- }
-
- // Inherit from SVG.Shape
- SVG.Path.prototype = new SVG.Shape
-
- SVG.extend(SVG.Path, {
- // Plot new poly points
- plot: function(p) {
- return this.attr('d', (this.array = new SVG.PathArray(p, [{ type:'M',x:0,y:0 }])))
- }
- // Move by left top corner
- , move: function(x, y) {
- return this.attr('d', this.array.move(x, y))
- }
- // Move by left top corner over x-axis
- , x: function(x) {
- return x == null ? this.bbox().x : this.move(x, this.bbox().y)
- }
- // Move by left top corner over y-axis
- , y: function(y) {
- return y == null ? this.bbox().y : this.move(this.bbox().x, y)
- }
- // Set element size to given width and height
- , size: function(width, height) {
- var p = this._proportionalSize(width, height)
-
- return this.attr('d', this.array.size(p.width, p.height))
- }
- // Set width of element
- , width: function(width) {
- return width == null ? this.bbox().width : this.size(width, this.bbox().height)
- }
- // Set height of element
- , height: function(height) {
- return height == null ? this.bbox().height : this.size(this.bbox().width, height)
+ SVG.Path = SVG.invent({
+ // Initialize node
+ create: 'path'
+
+ // Inherit from
+ , inherit: SVG.Shape
+
+ // Add class methods
+ , extend: {
+ // Plot new poly points
+ plot: function(p) {
+ return this.attr('d', (this.array = new SVG.PathArray(p, [{ type:'M',x:0,y:0 }])))
+ }
+ // Move by left top corner
+ , move: function(x, y) {
+ return this.attr('d', this.array.move(x, y))
+ }
+ // Move by left top corner over x-axis
+ , x: function(x) {
+ return x == null ? this.bbox().x : this.move(x, this.bbox().y)
+ }
+ // Move by left top corner over y-axis
+ , y: function(y) {
+ return y == null ? this.bbox().y : this.move(this.bbox().x, y)
+ }
+ // Set element size to given width and height
+ , size: function(width, height) {
+ var p = this._proportionalSize(width, height)
+
+ return this.attr('d', this.array.size(p.width, p.height))
+ }
+ // Set width of element
+ , width: function(width) {
+ return width == null ? this.bbox().width : this.size(width, this.bbox().height)
+ }
+ // Set height of element
+ , height: function(height) {
+ return height == null ? this.bbox().height : this.size(this.bbox().width, height)
+ }
}
-
- })
-
- //
- SVG.extend(SVG.Container, {
- // Create a wrapped path element
- path: function(d) {
- return this.put(new SVG.Path).plot(d)
+
+ // Add parent method
+ , construct: {
+ // Create a wrapped path element
+ path: function(d) {
+ return this.put(new SVG.Path).plot(d)
+ }
}
-
})
- SVG.Image = function() {
- this.constructor.call(this, SVG.create('image'))
- }
-
- // Inherit from SVG.Element
- SVG.Image.prototype = new SVG.Shape
-
- //
- SVG.extend(SVG.Image, {
- // (re)load image
- load: function(url) {
- return (url ? this.attr('href', (this.src = url), SVG.xlink) : this)
+ SVG.Image = SVG.invent({
+ // Initialize node
+ create: 'image'
+
+ // Inherit from
+ , inherit: SVG.Shape
+
+ // Add class methods
+ , extend: {
+ // (re)load image
+ load: function(url) {
+ return (url ? this.attr('href', (this.src = url), SVG.xlink) : this)
+ }
}
- })
-
- //
- SVG.extend(SVG.Container, {
- // Create image element, load image and set its size
- image: function(source, width, height) {
- width = width != null ? width : 100
- return this.put(new SVG.Image().load(source).size(width, height != null ? height : width))
+
+ // Add parent method
+ , construct: {
+ // Create image element, load image and set its size
+ image: function(source, width, height) {
+ width = width != null ? width : 100
+ return this.put(new SVG.Image().load(source).size(width, height != null ? height : width))
+ }
}
-
})
var _styleAttr = ('size family weight stretch variant style').split(' ')
- SVG.Text = function() {
- this.constructor.call(this, SVG.create('text'))
-
- /* define default style */
- this.styles = {
- 'font-size': 16
- , 'font-family': 'Helvetica, Arial, sans-serif'
- , 'text-anchor': 'start'
- }
-
- this._leading = new SVG.Number('1.2em')
- this._rebuild = true
- }
-
- // Inherit from SVG.Element
- SVG.Text.prototype = new SVG.Shape
-
- //
- SVG.extend(SVG.Text, {
- // Move over x-axis
- x: function(x, a) {
- /* act as getter */
- if (x == null)
- return a ? this.attr('x') : this.bbox().x
+ SVG.Text = SVG.invent({
+ // Initialize node
+ create: function() {
+ this.constructor.call(this, SVG.create('text'))
- /* set x taking anchor in mind */
- if (!a) {
- a = this.style('text-anchor')
- x = a == 'start' ? x : a == 'end' ? x + this.bbox().width : x + this.bbox().width / 2
+ /* define default style */
+ this.styles = {
+ 'font-size': 16
+ , 'font-family': 'Helvetica, Arial, sans-serif'
+ , 'text-anchor': 'start'
}
-
- /* move lines as well if no textPath si present */
- if (!this.textPath)
- this.lines.each(function() { if (this.newLined) this.x(x) })
-
- return this.attr('x', x)
- }
- // Move center over x-axis
- , cx: function(x, a) {
- return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2)
- }
- // Move center over y-axis
- , cy: function(y, a) {
- return y == null ? this.bbox().cy : this.y(a ? y : y - this.bbox().height / 2)
- }
- // Move element to given x and y values
- , move: function(x, y, a) {
- return this.x(x, a).y(y)
- }
- // Move element by its center
- , center: function(x, y, a) {
- return this.cx(x, a).cy(y, a)
- }
- // Set the text content
- , text: function(text) {
- /* act as getter */
- if (text == null)
- return this.content
-
- /* remove existing lines */
- this.clear()
- if (typeof text === 'function') {
- this._rebuild = false
+ this._leading = new SVG.Number('1.2em')
+ this._rebuild = true
+ }
- text.call(this, this)
+ // Inherit from
+ , inherit: SVG.Shape
- } else {
- this._rebuild = true
+ // Add class methods
+ , extend: {
+ // Move over x-axis
+ x: function(x, a) {
+ /* act as getter */
+ if (x == null)
+ return a ? this.attr('x') : this.bbox().x
+
+ /* set x taking anchor in mind */
+ if (!a) {
+ a = this.style('text-anchor')
+ x = a == 'start' ? x : a == 'end' ? x + this.bbox().width : x + this.bbox().width / 2
+ }
+
+ /* move lines as well if no textPath si present */
+ if (!this.textPath)
+ this.lines.each(function() { if (this.newLined) this.x(x) })
- /* make sure text is not blank */
- text = SVG.regex.isBlank.test(text) ? 'text' : text
+ return this.attr('x', x)
+ }
+ // Move center over x-axis
+ , cx: function(x, a) {
+ return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2)
+ }
+ // Move center over y-axis
+ , cy: function(y, a) {
+ return y == null ? this.bbox().cy : this.y(a ? y : y - this.bbox().height / 2)
+ }
+ // Move element to given x and y values
+ , move: function(x, y, a) {
+ return this.x(x, a).y(y)
+ }
+ // Move element by its center
+ , center: function(x, y, a) {
+ return this.cx(x, a).cy(y, a)
+ }
+ // Set the text content
+ , text: function(text) {
+ /* act as getter */
+ if (text == null)
+ return this.content
- var i, il
- , lines = text.split('\n')
+ /* remove existing lines */
+ this.clear()
- /* build new lines */
- for (i = 0, il = lines.length; i < il; i++)
- this.tspan(lines[i]).newLine()
+ if (typeof text === 'function') {
+ this._rebuild = false
- this.rebuild()
- }
-
- return this
- }
- // Create a tspan
- , tspan: function(text) {
- var node = this.textPath ? this.textPath.node : this.node
- , tspan = new SVG.TSpan().text(text)
- , style = this.style()
-
- /* add new tspan */
- node.appendChild(tspan.node)
- this.lines.add(tspan)
+ text.call(this, this)
- /* add style if any */
- if (!SVG.regex.isBlank.test(style))
- tspan.style(style)
+ } else {
+ this._rebuild = true
- /* store content */
- this.content += text
+ /* make sure text is not blank */
+ text = SVG.regex.isBlank.test(text) ? 'text' : text
+
+ var i, il
+ , lines = text.split('\n')
+
+ /* build new lines */
+ for (i = 0, il = lines.length; i < il; i++)
+ this.tspan(lines[i]).newLine()
- /* store text parent */
- tspan.parent = this
+ this.rebuild()
+ }
+
+ return this
+ }
+ // Create a tspan
+ , tspan: function(text) {
+ var node = this.textPath ? this.textPath.node : this.node
+ , tspan = new SVG.TSpan().text(text)
+ , style = this.style()
+
+ /* add new tspan */
+ node.appendChild(tspan.node)
+ this.lines.add(tspan)
- return tspan
- }
- // Set font size
- , size: function(size) {
- return this.attr('font-size', size)
- }
- // Set / get leading
- , leading: function(value) {
- /* act as getter */
- if (value == null)
- return this._leading
-
- /* act as setter */
- value = new SVG.Number(value)
- this._leading = value
-
- /* apply leading */
- this.lines.each(function() {
- if (this.newLined)
- this.attr('dy', value)
- })
+ /* add style if any */
+ if (!SVG.regex.isBlank.test(style))
+ tspan.style(style)
- return this
- }
- // rebuild appearance type
- , rebuild: function() {
- var self = this
+ /* store content */
+ this.content += text
+
+ /* store text parent */
+ tspan.parent = this
- /* define position of all lines */
- if (this._rebuild) {
- this.lines.attr({
- x: this.attr('x')
- , dy: this._leading
- , style: this.style()
+ return tspan
+ }
+ // Set font size
+ , size: function(size) {
+ return this.attr('font-size', size)
+ }
+ // Set / get leading
+ , leading: function(value) {
+ /* act as getter */
+ if (value == null)
+ return this._leading
+
+ /* act as setter */
+ value = new SVG.Number(value)
+ this._leading = value
+
+ /* apply leading */
+ this.lines.each(function() {
+ if (this.newLined)
+ this.attr('dy', value)
})
+
+ return this
}
+ // rebuild appearance type
+ , rebuild: function() {
+ var self = this
+
+ /* define position of all lines */
+ if (this._rebuild) {
+ this.lines.attr({
+ x: this.attr('x')
+ , dy: this._leading
+ , style: this.style()
+ })
+ }
- return this
- }
- // Clear all lines
- , clear: function() {
- var node = this.textPath ? this.textPath.node : this.node
+ return this
+ }
+ // Clear all lines
+ , clear: function() {
+ var node = this.textPath ? this.textPath.node : this.node
- /* remove existing child nodes */
- while (node.hasChildNodes())
- node.removeChild(node.lastChild)
-
- /* refresh lines */
- delete this.lines
- this.lines = new SVG.Set
-
- /* initialize content */
- this.content = ''
+ /* remove existing child nodes */
+ while (node.hasChildNodes())
+ node.removeChild(node.lastChild)
+
+ /* refresh lines */
+ delete this.lines
+ this.lines = new SVG.Set
+
+ /* initialize content */
+ this.content = ''
- return this
+ return this
+ }
}
- })
-
- //
- SVG.extend(SVG.Container, {
- // Create text element
- text: function(text) {
- return this.put(new SVG.Text).text(text)
+ // Add parent method
+ , construct: {
+ // Create text element
+ text: function(text) {
+ return this.put(new SVG.Text).text(text)
+ }
}
-
})
- // tspan class
- SVG.TSpan = function() {
- this.constructor.call(this, SVG.create('tspan'))
- }
+ SVG.TSpan = SVG.invent({
+ // Initialize node
+ create: 'tspan'
- // Inherit from SVG.Shape
- SVG.TSpan.prototype = new SVG.Shape
+ // Inherit from
+ , inherit: SVG.Shape
- // Include the container object
- SVG.extend(SVG.TSpan, {
- // Set text content
- text: function(text) {
- this.node.appendChild(document.createTextNode(text))
-
- return this
- }
- // Shortcut dx
- , dx: function(dx) {
- return this.attr('dx', dx)
- }
- // Shortcut dy
- , dy: function(dy) {
- return this.attr('dy', dy)
- }
- // Create new line
- , newLine: function() {
- this.newLined = true
- this.parent.content += '\n'
- this.dy(this.parent._leading)
- return this.attr('x', this.parent.x())
+ // Add class methods
+ , extend: {
+ // Set text content
+ text: function(text) {
+ this.node.appendChild(document.createTextNode(text))
+
+ return this
+ }
+ // Shortcut dx
+ , dx: function(dx) {
+ return this.attr('dx', dx)
+ }
+ // Shortcut dy
+ , dy: function(dy) {
+ return this.attr('dy', dy)
+ }
+ // Create new line
+ , newLine: function() {
+ this.newLined = true
+ this.parent.content += '\n'
+ this.dy(this.parent._leading)
+ return this.attr('x', this.parent.x())
+ }
}
-
+
})
+
- SVG.TextPath = function() {
- this.constructor.call(this, SVG.create('textPath'))
- }
+ SVG.TextPath = SVG.invent({
+ // Initialize node
+ create: 'textPath'
- // Inherit from SVG.Element
- SVG.TextPath.prototype = new SVG.Element
+ // Inherit from
+ , inherit: SVG.Element
- //
- SVG.extend(SVG.Text, {
- // Create path for text to run on
- path: function(d) {
- /* create textPath element */
- this.textPath = new SVG.TextPath
+ // Define parent class
+ , parent: SVG.Text
- /* move lines to textpath */
- while(this.node.hasChildNodes())
- this.textPath.node.appendChild(this.node.firstChild)
+ // Add parent method
+ , construct: {
+ // Create path for text to run on
+ path: function(d) {
+ /* create textPath element */
+ this.textPath = new SVG.TextPath
- /* add textPath element as child node */
- this.node.appendChild(this.textPath.node)
+ /* move lines to textpath */
+ while(this.node.hasChildNodes())
+ this.textPath.node.appendChild(this.node.firstChild)
- /* create path in defs */
- this.track = this.doc().defs().path(d, true)
+ /* add textPath element as child node */
+ this.node.appendChild(this.textPath.node)
- /* create circular reference */
- this.textPath.parent = this
+ /* create path in defs */
+ this.track = this.doc().defs().path(d, true)
- /* link textPath to path and add content */
- this.textPath.attr('href', '#' + this.track, SVG.xlink)
+ /* create circular reference */
+ this.textPath.parent = this
- return this
- }
- // Plot path if any
- , plot: function(d) {
- if (this.track) this.track.plot(d)
- return this
- }
+ /* link textPath to path and add content */
+ this.textPath.attr('href', '#' + this.track, SVG.xlink)
+ return this
+ }
+ // Plot path if any
+ , plot: function(d) {
+ if (this.track) this.track.plot(d)
+ return this
+ }
+ }
})
- SVG.Nested = function() {
- this.constructor.call(this, SVG.create('svg'))
-
- this.style('overflow', 'visible')
- }
-
- // Inherit from SVG.Container
- SVG.Nested.prototype = new SVG.Container
+ SVG.Nested = SVG.invent({
+ // Initialize node
+ create: function() {
+ this.constructor.call(this, SVG.create('svg'))
+
+ this.style('overflow', 'visible')
+ }
- //
- SVG.extend(SVG.Container, {
- // Create nested svg document
+ // Inherit from
+ , inherit: SVG.Container
+
+ // Add parent method
+ , construct: {
+ // Create nested svg document
nested: function() {
- return this.put(new SVG.Nested)
+ return this.put(new SVG.Nested)
+ }
}
-
})
- SVG.A = function() {
- this.constructor.call(this, SVG.create('a'))
- }
-
- // Inherit from SVG.Parent
- SVG.A.prototype = new SVG.Container
-
- //
- SVG.extend(SVG.A, {
- // Link url
- to: function(url) {
- return this.attr('href', url, SVG.xlink)
- }
- // Link show attribute
- , show: function(target) {
- return this.attr('show', target, SVG.xlink)
- }
- // Link target attribute
- , target: function(target) {
- return this.attr('target', target)
- }
-
- })
-
- //
- SVG.extend(SVG.Container, {
- // Create a hyperlink element
- link: function(url) {
- return this.put(new SVG.A).to(url)
+ SVG.A = SVG.invent({
+ // Initialize node
+ create: 'a'
+
+ // Inherit from
+ , inherit: SVG.Container
+
+ // Add class methods
+ , extend: {
+ // Link url
+ to: function(url) {
+ return this.attr('href', url, SVG.xlink)
+ }
+ // Link show attribute
+ , show: function(target) {
+ return this.attr('show', target, SVG.xlink)
+ }
+ // Link target attribute
+ , target: function(target) {
+ return this.attr('target', target)
+ }
}
+ // Add parent method
+ , construct: {
+ // Create a hyperlink element
+ link: function(url) {
+ return this.put(new SVG.A).to(url)
+ }
+ }
})
- //
SVG.extend(SVG.Element, {
// Create a hyperlink element
linkTo: function(url) {
@@ -3316,95 +3370,106 @@
- SVG.Set = function() {
- /* set initial state */
- this.clear()
- }
+ SVG.Set = SVG.invent({
+ // Initialize
+ create: function() {
+ /* set initial state */
+ this.clear()
+ }
- // Set FX class
- SVG.SetFX = function(set) {
- /* store reference to set */
- this.set = set
- }
+ // Add class methods
+ , extend: {
+ // Add element to set
+ add: function() {
+ var i, il, elements = [].slice.call(arguments)
- //
- SVG.extend(SVG.Set, {
- // Add element to set
- add: function() {
- var i, il, elements = [].slice.call(arguments)
+ for (i = 0, il = elements.length; i < il; i++)
+ this.members.push(elements[i])
+
+ return this
+ }
+ // Remove element from set
+ , remove: function(element) {
+ var i = this.index(element)
+
+ /* remove given child */
+ if (i > -1)
+ this.members.splice(i, 1)
- for (i = 0, il = elements.length; i < il; i++)
- this.members.push(elements[i])
-
- return this
- }
- // Remove element from set
- , remove: function(element) {
- var i = this.index(element)
-
- /* remove given child */
- if (i > -1)
- this.members.splice(i, 1)
+ return this
+ }
+ // Iterate over all members
+ , each: function(block) {
+ for (var i = 0, il = this.members.length; i < il; i++)
+ block.apply(this.members[i], [i, this.members])
- return this
- }
- // Iterate over all members
- , each: function(block) {
- for (var i = 0, il = this.members.length; i < il; i++)
- block.apply(this.members[i], [i, this.members])
+ return this
+ }
+ // Restore to defaults
+ , clear: function() {
+ /* initialize store */
+ this.members = []
- return this
- }
- // Restore to defaults
- , clear: function() {
- /* initialize store */
- this.members = []
+ return this
+ }
+ // Checks if a given element is present in set
+ , has: function(element) {
+ return this.index(element) >= 0
+ }
+ // retuns index of given element in set
+ , index: function(element) {
+ return this.members.indexOf(element)
+ }
+ // Get member at given index
+ , get: function(i) {
+ return this.members[i]
+ }
+ // Default value
+ , valueOf: function() {
+ return this.members
+ }
+ // Get the bounding box of all members included or empty box if set has no items
+ , bbox: function(){
+ var box = new SVG.BBox()
+
+ /* return an empty box of there are no members */
+ if (this.members.length == 0)
+ return box
+
+ /* get the first rbox and update the target bbox */
+ var rbox = this.members[0].rbox()
+ box.x = rbox.x
+ box.y = rbox.y
+ box.width = rbox.width
+ box.height = rbox.height
+
+ this.each(function() {
+ /* user rbox for correct position and visual representation */
+ box = box.merge(this.rbox())
+ })
- return this
- }
- // Checks if a given element is present in set
- , has: function(element) {
- return this.index(element) >= 0
- }
- // retuns index of given element in set
- , index: function(element) {
- return this.members.indexOf(element)
- }
- // Get member at given index
- , get: function(i) {
- return this.members[i]
+ return box
+ }
}
- // Default value
- , valueOf: function() {
- return this.members
+
+ // Add parent method
+ , construct: {
+ // Create a new set
+ set: function() {
+ return new SVG.Set
+ }
}
- // Get the bounding box of all members included or empty box if set has no items
- , bbox: function(){
- var box = new SVG.BBox()
-
- /* return an empty box of there are no members */
- if (this.members.length == 0)
- return box
-
- /* get the first rbox and update the target bbox */
- var rbox = this.members[0].rbox()
- box.x = rbox.x
- box.y = rbox.y
- box.width = rbox.width
- box.height = rbox.height
-
- this.each(function() {
- /* user rbox for correct position and visual representation */
- box = box.merge(this.rbox())
- })
+ })
- return box
+ SVG.SetFX = SVG.invent({
+ // Initialize node
+ create: function(set) {
+ /* store reference to set */
+ this.set = set
}
})
-
-
// Alias methods
SVG.Set.inherit = function() {
var m
@@ -3445,16 +3510,6 @@
})
}
- //
- SVG.extend(SVG.Container, {
- // Create a new set
- set: function() {
- return new SVG.Set
- }
-
- })
-
-
diff --git a/dist/svg.min.js b/dist/svg.min.js
index 2e2a5ea..bba1267 100644
--- a/dist/svg.min.js
+++ b/dist/svg.min.js
@@ -1,2 +1,2 @@
-(function(){function t(t,e){return"number"==typeof t.from?t.from+(t.to-t.from)*e:t instanceof SVG.Color||t instanceof SVG.Number?t.at(e):1>e?t.from:t.to}if(this.SVG=function(t){return SVG.parser||SVG.prepare(),SVG.supported?new SVG.Doc(t):void 0},SVG.ns="http://www.w3.org/2000/svg",SVG.xmlns="http://www.w3.org/2000/xmlns/",SVG.xlink="http://www.w3.org/1999/xlink",SVG.did=1e3,SVG.eid=function(t){return"Svgjs"+t.charAt(0).toUpperCase()+t.slice(1)+SVG.did++},SVG.create=function(t){var e=document.createElementNS(this.ns,t);return e.setAttribute("id",this.eid(t)),e},SVG.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];SVG.Set&&SVG.Set.inherit&&SVG.Set.inherit()},SVG.get=function(t){var e=document.getElementById(t);return e?e.instance:void 0},SVG.prepare=function(){var t=document.getElementsByTagName("body")[0]||document.getElementsByTagName("svg")[0],e=new SVG.Doc(t).size(2,2).style("opacity:0;position:fixed;left:100%;top:100%;");SVG.parser={body:t,draw:e,poly:e.polygon().node,path:e.path().node}},SVG.supported=function(){return!!document.createElementNS&&!!document.createElementNS(SVG.ns,"svg").createSVGRect}(),!SVG.supported)return!1;SVG.regex={test:function(t,e){return this[e].test(t)},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:/[^:]+:[^;]+;?/,isStyle:/^font|text|leading|cursor/,isBlank:/^(\s+)?$/,isNumber:/^-?[\d\.]+$/,isPercent:/^-?[\d\.]+%$/},SVG.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"},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}}},SVG.Color=function(t){var e;this.r=0,this.g=0,this.b=0,"string"==typeof t?SVG.regex.isRgb.test(t)?(e=SVG.regex.rgb.exec(t.replace(/\s/g,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):SVG.regex.isHex.test(t)&&(e=SVG.regex.hex.exec(this._fullHex(t)),this.r=parseInt(e[1],16),this.g=parseInt(e[2],16),this.b=parseInt(e[3],16)):"object"==typeof t&&(this.r=t.r,this.g=t.g,this.b=t.b)},SVG.extend(SVG.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+this._compToHex(this.r)+this._compToHex(this.g)+this._compToHex(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return.3*(this.r/255)+.59*(this.g/255)+.11*(this.b/255)},morph:function(t){return this.destination=new SVG.Color(t),this},at:function(t){return this.destination?(t=0>t?0:t>1?1:t,new SVG.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},_fullHex:function(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},_compToHex:function(t){var e=t.toString(16);return 1==e.length?"0"+e:e}}),SVG.Color.test=function(t){return t+="",SVG.regex.isHex.test(t)||SVG.regex.isRgb.test(t)},SVG.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},SVG.Color.isColor=function(t){return SVG.Color.isRgb(t)||SVG.Color.test(t)},SVG.Array=function(t,e){t=(t||[]).valueOf(),0==t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},SVG.extend(SVG.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 SVG.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(" ")}}),SVG.PointArray=function(){this.constructor.apply(this,arguments)},SVG.PointArray.prototype=new SVG.Array,SVG.extend(SVG.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 SVG.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.x;return this},bbox:function(){return this._cachedBBox?this._cachedBBox:(SVG.parser.poly.setAttribute("points",this.toString()),SVG.parser.poly.getBBox())}}),SVG.PathArray=function(t,e){this.constructor.call(this,t,e)},SVG.PathArray.prototype=new SVG.Array,SVG.extend(SVG.PathArray,{toString:function(){for(var t,e=0,i=this.value.length,n=[];i>e;e++){switch(t=[this.value[e].type],this.value[e].type){case"H":t.push(this.value[e].x);break;case"V":t.push(this.value[e].y);break;case"M":case"L":case"T":case"S":case"Q":case"C":/[QC]/.test(this.value[e].type)&&t.push(this.value[e].x1,this.value[e].y1),/[CS]/.test(this.value[e].type)&&t.push(this.value[e].x2,this.value[e].y2),t.push(this.value[e].x,this.value[e].y);break;case"A":t.push(this.value[e].rx,this.value[e].ry,this.value[e].angle,this.value[e].largeArcFlag,this.value[e].sweepFlag,this.value[e].x,this.value[e].y)}n.push(t.join(" "))}return n.join(" ")},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--)switch(this.value[n].type){case"H":this.value[n].x+=t;break;case"V":this.value[n].y+=e;break;case"M":case"L":case"T":case"S":case"Q":case"C":this.value[n].x+=t,this.value[n].y+=e,/[CQ]/.test(this.value[n].type)&&(this.value[n].x1+=t,this.value[n].y1+=e),/[CS]/.test(this.value[n].type)&&(this.value[n].x2+=t,this.value[n].y2+=e);break;case"A":this.value[n].x+=t,this.value[n].y+=e}return this},size:function(t,e){for(var i=this.bbox(),n=this.value.length-1;n>=0;n--)switch(this.value[n].type){case"H":this.value[n].x=(this.value[n].x-i.x)*t/i.width+i.x;break;case"V":this.value[n].y=(this.value[n].y-i.y)*e/i.height+i.y;break;case"M":case"L":case"T":case"S":case"Q":case"C":this.value[n].x=(this.value[n].x-i.x)*t/i.width+i.x,this.value[n].y=(this.value[n].y-i.y)*e/i.height+i.y,/[CQ]/.test(this.value[n].type)&&(this.value[n].x1=(this.value[n].x1-i.x)*t/i.width+i.x,this.value[n].y1=(this.value[n].y1-i.y)*e/i.height+i.y),/[CS]/.test(this.value[n].type)&&(this.value[n].x2=(this.value[n].x2-i.x)*t/i.width+i.x,this.value[n].y2=(this.value[n].y2-i.y)*e/i.height+i.y);break;case"A":this.value[n].values.rx=this.value[n].values.rx*t/i.width,this.value[n].values.ry=this.value[n].values.ry*e/i.height,this.value[n].values.x=(this.value[n].values.x-i.x)*t/i.width+i.x,this.value[n].values.y=(this.value[n].values.y-i.y)*e/i.height+i.y}return this},parse:function(t){if(t=t.valueOf(),Array.isArray(t))return t;var e,i,n,r,s,h,o,a,u,l,c,f=0,p=0;for(SVG.parser.path.setAttribute("d",t),c=SVG.parser.path.pathSegList,e=0,i=c.numberOfItems;i>e;++e){if(l=c.getItem(e),u=l.pathSegTypeAsLetter,/[MLHVCSQTA]/.test(u))"x"in l&&(f=l.x),"y"in l&&(p=l.y);else switch("x1"in l&&(s=f+l.x1),"x2"in l&&(o=f+l.x2),"y1"in l&&(h=p+l.y1),"y2"in l&&(a=p+l.y2),"x"in l&&(f+=l.x),"y"in l&&(p+=l.y),u){case"m":c.replaceItem(SVG.parser.path.createSVGPathSegMovetoAbs(f,p),e);break;case"l":c.replaceItem(SVG.parser.path.createSVGPathSegLinetoAbs(f,p),e);break;case"h":c.replaceItem(SVG.parser.path.createSVGPathSegLinetoHorizontalAbs(f),e);break;case"v":c.replaceItem(SVG.parser.path.createSVGPathSegLinetoVerticalAbs(p),e);break;case"c":c.replaceItem(SVG.parser.path.createSVGPathSegCurvetoCubicAbs(f,p,s,h,o,a),e);break;case"s":c.replaceItem(SVG.parser.path.createSVGPathSegCurvetoCubicSmoothAbs(f,p,o,a),e);break;case"q":c.replaceItem(SVG.parser.path.createSVGPathSegCurvetoQuadraticAbs(f,p,s,h),e);break;case"t":c.replaceItem(SVG.parser.path.createSVGPathSegCurvetoQuadraticSmoothAbs(f,p),e);break;case"a":c.replaceItem(SVG.parser.path.createSVGPathSegArcAbs(f,p,l.r1,l.r2,l.angle,l.largeArcFlag,l.sweepFlag),e);break;case"z":case"Z":f=n,p=r}/[Mm]/.test(u)&&(n=f,r=p)}for(t=[],c=SVG.parser.path.pathSegList,e=0,i=c.numberOfItems;i>e;++e){switch(l=c.getItem(e),u={},l.pathSegTypeAsLetter){case"M":case"L":case"T":case"S":case"Q":case"C":/[QC]/.test(l.pathSegTypeAsLetter)&&(u.x1=l.x1,u.y1=l.y1),/[SC]/.test(l.pathSegTypeAsLetter)&&(u.x2=l.x2,u.y2=l.y2);break;case"A":u={r1:l.r1,r2:l.r2,a:l.angle,l:l.largeArcFlag,s:l.sweepFlag}}u.type=l.pathSegTypeAsLetter,u.x=l.x,u.y=l.y,t.push(u)}return t},bbox:function(){return this._cachedBBox?this._cachedBBox:(SVG.parser.path.setAttribute("d",this.toString()),SVG.parser.path.getBBox())}}),SVG.Number=function(t){switch(this.value=0,this.unit="",typeof t){case"number":this.value=isNaN(t)?0:isFinite(t)?t:0>t?-3.4e38:3.4e38;break;case"string":var e=t.match(SVG.regex.unit);e&&(this.value=parseFloat(e[1]),"%"==e[2]&&(this.value/=100),this.unit=e[2]);break;default:t instanceof SVG.Number&&(this.value=t.value,this.unit=t.unit)}},SVG.extend(SVG.Number,{toString:function(){return("%"==this.unit?~~(1e8*this.value)/1e6:this.value)+this.unit},valueOf:function(){return this.value},plus:function(t){return this.value=this+new SVG.Number(t),this},minus:function(t){return this.plus(-new SVG.Number(t))},times:function(t){return this.value=this*new SVG.Number(t),this},divide:function(t){return this.value=this/new SVG.Number(t),this},to:function(t){return"string"==typeof t&&(this.unit=t),this},morph:function(t){return this.destination=new SVG.Number(t),this},at:function(t){return this.destination?new SVG.Number(this.destination).minus(this).times(t).plus(this):this}}),SVG.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 SVG.Number(t.width()),r=new SVG.Number(t.height());"%"==n.unit;)s*=n.value,n=new SVG.Number(t instanceof SVG.Doc?t.parent.offsetWidth:t.width());for(;"%"==r.unit;)h*=r.value,r=new SVG.Number(t instanceof SVG.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)},SVG.extend(SVG.ViewBox,{toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height}}),SVG.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}this.cx=this.x+this.width/2,this.cy=this.y+this.height/2},SVG.extend(SVG.BBox,{merge:function(t){var e=new SVG.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,e.cx=e.x+e.width/2,e.cy=e.y+e.height/2,e}}),SVG.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.cx=this.x+this.width/2,this.cy=this.y+this.height/2},SVG.extend(SVG.RBox,{merge:function(t){var e=new SVG.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,e.cx=e.x+e.width/2,e.cy=e.y+e.height/2,e}}),SVG.Element=function(t){this._stroke=SVG.defaults.attrs.stroke,this.styles={},this.trans=SVG.defaults.trans(),(this.node=t)&&(this.type=t.nodeName,this.node.instance=this)},SVG.extend(SVG.Element,{x:function(t){return t&&(t=new SVG.Number(t),t.value/=this.trans.scaleX),this.attr("x",t)},y:function(t){return t&&(t=new SVG.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=this._proportionalSize(t,e);return this.attr({width:new SVG.Number(i.width),height:new SVG.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||SVG.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]=SVG.regex.test(e[i].nodeValue,"isNumber")?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 this._isStyle(t)?"text"==t?this.content:"leading"==t&&this.leading?this.leading():this.style(t):(e=this.node.getAttribute(t),null==e?SVG.defaults.attrs[t]:SVG.regex.test(e,"isNumber")?parseFloat(e):e);if("style"==t)return this.style(e);if("x"==t&&Array.isArray(this.lines))for(i=this.lines.length-1;i>=0;i--)this.lines[i].attr(t,e);"stroke-width"==t?this.attr("stroke",parseFloat(e)>0?this._stroke:null):"stroke"==t&&(this._stroke=e),SVG.Color.test(e)||SVG.Color.isRgb(e)?e=new SVG.Color(e):"number"==typeof e?e=new SVG.Number(e):Array.isArray(e)&&(e=new SVG.Array(e)),null!=i?this.node.setAttributeNS(i,t,e.toString()):this.node.setAttribute(t,e.toString()),this._isStyle(t)&&("text"==t?this.text(e):"leading"==t&&this.leading?this.leading(e):this.style(t,e),this.rebuild&&this.rebuild(t,e))}return this},transform:function(t,e){if(0==arguments.length)return this.trans;if("string"==typeof t){if(2>arguments.length)return this.trans[t];var i={};return i[t]=e,this.transform(i)}var i=[];t=this._parseMatrix(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!=SVG.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 SVG.Number(t.x/t.scaleX)+" "+new SVG.Number(t.y/t.scaleY)+")"),0==i.length?this.node.removeAttribute("transform"):this.node.setAttribute("transform",i.join(" ")),this},style:function(t,e){if(0==arguments.length)return this.attr("style")||"";if(2>arguments.length)if("object"==typeof t)for(e in t)this.style(e,t[e]);else{if(!SVG.regex.isCss.test(t))return this.styles[t];t=t.split(";");for(var i=0;t.length>i;i++)e=t[i].split(":"),2==e.length&&this.style(e[0].replace(/\s+/g,""),e[1].replace(/^\s+/,"").replace(/\s+$/,""))}else null===e||SVG.regex.test(e,"isBlank")?delete this.styles[t]:this.styles[t]=e;t="";for(e in this.styles)t+=e+":"+this.styles[e]+";";return""==t?this.node.removeAttribute("style"):this.node.setAttribute("style",t),this},bbox:function(){return new SVG.BBox(this)},rbox:function(){return new SVG.RBox(this)},inside:function(t,e){var i=this.bbox();return t>i.x&&e>i.y&&i.x+i.width>t&&i.y+i.height>e},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")},_parent:function(t){for(var e=this;null!=e&&!(e instanceof t);)e=e.parent;return e},_isStyle:function(t){return"string"==typeof t?SVG.regex.test(t,"isStyle"):!1},_parseMatrix:function(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},_proportionalSize:function(t,e){if(null==t||null==e){var i=this.bbox();null==e?e=i.height/i.width*t:null==t&&(t=i.width/i.height*e)}return{width:t,height:e}}}),SVG.Parent=function(t){this.constructor.call(this,t)},SVG.Parent.prototype=new SVG.Element,SVG.extend(SVG.Parent,{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 SVG.Element&&t.apply(r[i],[i,r]),e&&r[i]instanceof SVG.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()}}),SVG.Container=function(t){this.constructor.call(this,t)},SVG.Container.prototype=new SVG.Parent,SVG.extend(SVG.Container,{viewbox:function(t){return 0==arguments.length?new SVG.ViewBox(this):(t=1==arguments.length?[t.x,t.y,t.width,t.height]:[].slice.call(arguments),this.attr("viewBox",t))}}),SVG.FX=function(t){this.target=t},SVG.extend(SVG.FX,{animate:function(e,i,n){var r,s,h,o,a=this.target,u=this;return"object"==typeof e&&(n=e.delay,i=e.ease,e=e.duration),e=null==e?1e3:e,i=i||"<>",u.to=function(e){var n;if(e=0>e?0:e>1?1:e,null==r){r=[];for(o in u.attrs)r.push(o);if(a.morphArray&&(u._plot||r.indexOf("points")>-1)){var l,c=new a.morphArray(u._plot||u.attrs.points||a.array);u._size&&c.size(u._size.width.to,u._size.height.to),l=c.bbox(),u._x?c.move(u._x.to,l.y):u._cx&&c.move(u._cx.to-l.width/2,l.y),l=c.bbox(),u._y?c.move(l.x,u._y.to):u._cy&&c.move(l.x,u._cy.to-l.height/2),delete u._x,delete u._y,delete u._cx,delete u._cy,delete u._size,u._plot=a.array.morph(c)}}if(null==s){s=[];for(o in u.trans)s.push(o)}if(null==h){h=[];for(o in u.styles)h.push(o)}for(e="<>"==i?-Math.cos(e*Math.PI)/2+.5:">"==i?Math.sin(e*Math.PI/2):"<"==i?-Math.cos(e*Math.PI/2)+1:"-"==i?e:"function"==typeof i?i(e):e,u._plot?a.plot(u._plot.at(e)):(u._x?a.x(t(u._x,e)):u._cx&&a.cx(t(u._cx,e)),u._y?a.y(t(u._y,e)):u._cy&&a.cy(t(u._cy,e)),u._size&&a.size(t(u._size.width,e),t(u._size.height,e))),u._viewbox&&a.viewbox(t(u._viewbox.x,e),t(u._viewbox.y,e),t(u._viewbox.width,e),t(u._viewbox.height,e)),n=r.length-1;n>=0;n--)a.attr(r[n],t(u.attrs[r[n]],e));for(n=s.length-1;n>=0;n--)a.transform(s[n],t(u.trans[s[n]],e));for(n=h.length-1;n>=0;n--)a.style(h[n],t(u.styles[h[n]],e));u._during&&u._during.call(a,e,function(i,n){return t({from:i,to:n},e)})},"number"==typeof e&&(this.timeout=setTimeout(function(){var t=(new Date).getTime();u.situation={interval:1e3/60,start:t,play:!0,finish:t+e,duration:e},u.render=function(){if(u.situation.play===!0){var t=(new Date).getTime(),r=t>u.situation.finish?1:(t-u.situation.start)/e;u.to(r),t>u.situation.finish?(u._plot&&a.plot(new SVG.PointArray(u._plot.destination).settle()),u._loop===!0||"number"==typeof u._loop&&u._loop>1?("number"==typeof u._loop&&--u._loop,u.animate(e,i,n)):u._after?u._after.apply(a,[u]):u.stop()):requestAnimFrame(u.render)}else requestAnimFrame(u.render)},u.render()},n||0)),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]=SVG.Color.isColor(n)?new SVG.Color(n).morph(e):SVG.regex.unit.test(n)?new SVG.Number(n).morph(e):{from:n,to:e}}return this},transform:function(t,e){if(1==arguments.length){t=this.target._parseMatrix(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={from:this.target.x(),to:t},this},y:function(t){return this._y={from:this.target.y(),to:t},this},cx:function(t){return this._cx={from:this.target.cx(),to:t},this},cy:function(t){return this._cy={from:this.target.cy(),to: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 SVG.Text)this.attr("font-size",t);else{var i=this.target.bbox();this._size={width:{from:i.width,to:t},height:{from:i.height,to:e}}}return this},plot:function(t){return this._plot=t,this},viewbox:function(t,e,i,n){if(this.target instanceof SVG.Container){var r=this.target.viewbox();this._viewbox={x:{from:r.x,to:t},y:{from:r.y,to:e},width:{from:r.width,to:i},height:{from:r.height,to:n}}}return this},update:function(t){return this.target instanceof SVG.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 SVG.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(){return clearTimeout(this.timeout),clearInterval(this.interval),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._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}}),SVG.extend(SVG.Element,{animate:function(t,e,i){return(this.fx||(this.fx=new SVG.FX(this))).stop().animate(t,e,i)},stop:function(){return this.fx&&this.fx.stop(),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this}}),window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)}}(),SVG.extend(SVG.Element,SVG.FX,{relative:function(){var t,e=this;return{x:function(i){return t=e.bbox(),e.x(t.x+(i||0))},y:function(i){return t=e.bbox(),e.y(t.y+(i||0))},move:function(t,e){return this.x(t),this.y(e)}}}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave"].forEach(function(t){SVG.Element.prototype[t]=function(e){var i=this;return this.node["on"+t]="function"==typeof e?function(){return e.apply(i,arguments)}:null,this}}),SVG.on=function(t,e,i){t.addEventListener?t.addEventListener(e,i,!1):t.attachEvent("on"+e,i)},SVG.off=function(t,e,i){t.removeEventListener?t.removeEventListener(e,i,!1):t.detachEvent("on"+e,i)},SVG.extend(SVG.Element,{on:function(t,e){return SVG.on(this.node,t,e),this},off:function(t,e){return SVG.off(this.node,t,e),this}}),SVG.Defs=function(){this.constructor.call(this,SVG.create("defs"))},SVG.Defs.prototype=new SVG.Container,SVG.G=function(){this.constructor.call(this,SVG.create("g"))},SVG.G.prototype=new SVG.Container,SVG.extend(SVG.G,{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)}}),SVG.extend(SVG.Container,{group:function(){return this.put(new SVG.G)}}),SVG.extend(SVG.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}}),SVG.Mask=function(){this.constructor.call(this,SVG.create("mask")),this.targets=[]},SVG.Mask.prototype=new SVG.Container,SVG.extend(SVG.Mask,{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}}),SVG.extend(SVG.Element,{maskWith:function(t){return this.masker=t instanceof SVG.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)}}),SVG.extend(SVG.Container,{mask:function(){return this.defs().put(new SVG.Mask)}}),SVG.Clip=function(){this.constructor.call(this,SVG.create("clipPath")),this.targets=[]},SVG.Clip.prototype=new SVG.Container,SVG.extend(SVG.Clip,{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}}),SVG.extend(SVG.Element,{clipWith:function(t){return this.clipper=t instanceof SVG.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)}}),SVG.extend(SVG.Container,{clip:function(){return this.defs().put(new SVG.Clip)}}),SVG.Gradient=function(t){this.constructor.call(this,SVG.create(t+"Gradient")),this.type=t},SVG.Gradient.prototype=new SVG.Container,SVG.extend(SVG.Gradient,{from:function(t,e){return"radial"==this.type?this.attr({fx:new SVG.Number(t),fy:new SVG.Number(e)}):this.attr({x1:new SVG.Number(t),y1:new SVG.Number(e)})},to:function(t,e){return"radial"==this.type?this.attr({cx:new SVG.Number(t),cy:new SVG.Number(e)}):this.attr({x2:new SVG.Number(t),y2:new SVG.Number(e)})},radius:function(t){return"radial"==this.type?this.attr({r:new SVG.Number(t)}):this},at:function(t){return this.put(new SVG.Stop(t))},update:function(t){return this.clear(),t(this),this},fill:function(){return"url(#"+this.attr("id")+")"},toString:function(){return this.fill()}}),SVG.extend(SVG.Defs,{gradient:function(t,e){var i=this.put(new SVG.Gradient(t));return e(i),i}}),SVG.extend(SVG.Container,{gradient:function(t,e){return this.defs().gradient(t,e)}}),SVG.Stop=function(t){this.constructor.call(this,SVG.create("stop")),this.update(t)},SVG.Stop.prototype=new SVG.Element,SVG.extend(SVG.Stop,{update:function(t){return 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 SVG.Number(t.offset)),this}}),SVG.Doc=function(t){this.parent="string"==typeof t?document.getElementById(t):t,this.constructor.call(this,"svg"==this.parent.nodeName?this.parent:SVG.create("svg")),this.attr({xmlns:SVG.ns,version:"1.1",width:"100%",height:"100%"}).attr("xmlns:xlink",SVG.xlink,SVG.xmlns),this._defs=new SVG.Defs,this._defs.parent=this,this.node.appendChild(this._defs.node),this.doSubPixelOffsetFix=!1,"svg"!=this.parent.nodeName&&this.stage()},SVG.Doc.prototype=new SVG.Container,SVG.extend(SVG.Doc,{stage:function(){var t,e=this,i=document.createElement("div");return i.style.cssText="position:relative;height:100%;",e.parent.appendChild(i),i.appendChild(e.node),t=function(){"complete"===document.readyState?(e.style("position:absolute;"),setTimeout(function(){e.style("position:relative;overflow:hidden;"),e.parent.removeChild(e.node.parentNode),e.node.parentNode.removeChild(e.node),e.parent.appendChild(e.node),e.subPixelOffsetFix(),SVG.on(window,"resize",function(){e.subPixelOffsetFix()})},5)):setTimeout(t,10)},t(),this},defs:function(){return this._defs},subPixelOffsetFix:function(){if(this.doSubPixelOffsetFix){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.doSubPixelOffsetFix=!0,this}}),SVG.Shape=function(t){this.constructor.call(this,t)},SVG.Shape.prototype=new SVG.Element,SVG.Use=function(){this.constructor.call(this,SVG.create("use"))},SVG.Use.prototype=new SVG.Shape,SVG.extend(SVG.Use,{element:function(t){return this.target=t,this.attr("href","#"+t,SVG.xlink)}}),SVG.extend(SVG.Container,{use:function(t){return this.put(new SVG.Use).element(t)}}),SVG.Rect=function(){this.constructor.call(this,SVG.create("rect"))},SVG.Rect.prototype=new SVG.Shape,SVG.extend(SVG.Container,{rect:function(t,e){return this.put((new SVG.Rect).size(t,e))}}),SVG.Ellipse=function(){this.constructor.call(this,SVG.create("ellipse"))},SVG.Ellipse.prototype=new SVG.Shape,SVG.extend(SVG.Ellipse,{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 SVG.Number(t).divide(this.trans.scaleX))},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",new SVG.Number(t).divide(this.trans.scaleY))},width:function(t){return null==t?2*this.attr("rx"):this.attr("rx",new SVG.Number(t).divide(2))},height:function(t){return null==t?2*this.attr("ry"):this.attr("ry",new SVG.Number(t).divide(2))},size:function(t,e){var i=this._proportionalSize(t,e);return this.attr({rx:new SVG.Number(i.width).divide(2),ry:new SVG.Number(i.height).divide(2)})}}),SVG.extend(SVG.Container,{circle:function(t){return this.ellipse(t,t)},ellipse:function(t,e){return this.put(new SVG.Ellipse).size(t,e).move(0,0)}}),SVG.Line=function(){this.constructor.call(this,SVG.create("line"))},SVG.Line.prototype=new SVG.Shape,SVG.extend(SVG.Line,{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=this._proportionalSize(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})}}),SVG.extend(SVG.Container,{line:function(t,e,i,n){return this.put((new SVG.Line).plot(t,e,i,n))}}),SVG.Polyline=function(){this.constructor.call(this,SVG.create("polyline"))},SVG.Polyline.prototype=new SVG.Shape,SVG.Polygon=function(){this.constructor.call(this,SVG.create("polygon"))},SVG.Polygon.prototype=new SVG.Shape,SVG.extend(SVG.Polyline,SVG.Polygon,{morphArray:SVG.PointArray,plot:function(t){return this.attr("points",this.array=new SVG.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=this._proportionalSize(t,e);return this.attr("points",this.array.size(i.width,i.height))}}),SVG.extend(SVG.Container,{polyline:function(t){return this.put(new SVG.Polyline).plot(t)},polygon:function(t){return this.put(new SVG.Polygon).plot(t)}}),SVG.Path=function(){this.constructor.call(this,SVG.create("path"))},SVG.Path.prototype=new SVG.Shape,SVG.extend(SVG.Path,{plot:function(t){return this.attr("d",this.array=new SVG.PathArray(t,[{type:"M",x:0,y: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=this._proportionalSize(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)}}),SVG.extend(SVG.Container,{path:function(t){return this.put(new SVG.Path).plot(t)}}),SVG.Image=function(){this.constructor.call(this,SVG.create("image"))},SVG.Image.prototype=new SVG.Shape,SVG.extend(SVG.Image,{load:function(t){return t?this.attr("href",this.src=t,SVG.xlink):this}}),SVG.extend(SVG.Container,{image:function(t,e,i){return e=null!=e?e:100,this.put((new SVG.Image).load(t).size(e,null!=i?i:e))}});var e="size family weight stretch variant style".split(" ");SVG.Text=function(){this.constructor.call(this,SVG.create("text")),this.styles={"font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"},this._leading=new SVG.Number("1.2em"),this._rebuild=!0},SVG.Text.prototype=new SVG.Shape,SVG.extend(SVG.Text,{x:function(t,e){return null==t?e?this.attr("x"):this.bbox().x:(e||(e=this.style("text-anchor"),t="start"==e?t:"end"==e?t+this.bbox().width:t+this.bbox().width/2),this.textPath||this.lines.each(function(){this.newLined&&this.x(t)}),this.attr("x",t))},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t,e){return null==t?this.bbox().cy:this.y(e?t:t-this.bbox().height/2)},move:function(t,e,i){return this.x(t,i).y(e)},center:function(t,e,i){return this.cx(t,i).cy(e,i)},text:function(t){if(null==t)return this.content;if(this.clear(),"function"==typeof t)this._rebuild=!1,t.call(this,this);else{this._rebuild=!0,t=SVG.regex.isBlank.test(t)?"text":t;var e,i,n=t.split("\n");for(e=0,i=n.length;i>e;e++)this.tspan(n[e]).newLine();this.rebuild()}return this},tspan:function(t){var e=this.textPath?this.textPath.node:this.node,i=(new SVG.TSpan).text(t),n=this.style();return e.appendChild(i.node),this.lines.add(i),SVG.regex.isBlank.test(n)||i.style(n),this.content+=t,i.parent=this,i},size:function(t){return this.attr("font-size",t)},leading:function(t){return null==t?this._leading:(t=new SVG.Number(t),this._leading=t,this.lines.each(function(){this.newLined&&this.attr("dy",t)}),this)},rebuild:function(){return this._rebuild&&this.lines.attr({x:this.attr("x"),dy:this._leading,style:this.style()}),this},clear:function(){for(var t=this.textPath?this.textPath.node:this.node;t.hasChildNodes();)t.removeChild(t.lastChild);return delete this.lines,this.lines=new SVG.Set,this.content="",this}}),SVG.extend(SVG.Container,{text:function(t){return this.put(new SVG.Text).text(t)}}),SVG.TSpan=function(){this.constructor.call(this,SVG.create("tspan"))},SVG.TSpan.prototype=new SVG.Shape,SVG.extend(SVG.TSpan,{text:function(t){return this.node.appendChild(document.createTextNode(t)),this},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){return this.newLined=!0,this.parent.content+="\n",this.dy(this.parent._leading),this.attr("x",this.parent.x())}}),SVG.TextPath=function(){this.constructor.call(this,SVG.create("textPath"))},SVG.TextPath.prototype=new SVG.Element,SVG.extend(SVG.Text,{path:function(t){for(this.textPath=new SVG.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,!0),this.textPath.parent=this,this.textPath.attr("href","#"+this.track,SVG.xlink),this},plot:function(t){return this.track&&this.track.plot(t),this}}),SVG.Nested=function(){this.constructor.call(this,SVG.create("svg")),this.style("overflow","visible")},SVG.Nested.prototype=new SVG.Container,SVG.extend(SVG.Container,{nested:function(){return this.put(new SVG.Nested)}}),SVG.A=function(){this.constructor.call(this,SVG.create("a"))},SVG.A.prototype=new SVG.Container,SVG.extend(SVG.A,{to:function(t){return this.attr("href",t,SVG.xlink)},show:function(t){return this.attr("show",t,SVG.xlink)},target:function(t){return this.attr("target",t)}}),SVG.extend(SVG.Container,{link:function(t){return this.put(new SVG.A).to(t)}}),SVG.extend(SVG.Element,{linkTo:function(t){var e=new SVG.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent.put(e).put(this)}}),SVG._stroke=["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],SVG._fill=["color","opacity","rule"];var i=function(t,e){return"color"==e?t:t+"-"+e};["fill","stroke"].forEach(function(t){var e={};e[t]=function(e){if("string"==typeof e||SVG.Color.isRgb(e)||e&&"function"==typeof e.fill)this.attr(t,e);else for(index=SVG["_"+t].length-1;index>=0;index--)null!=e[SVG["_"+t][index]]&&this.attr(i(t,SVG["_"+t][index]),e[SVG["_"+t][index]]);return this},SVG.extend(SVG.Element,SVG.FX,e)}),SVG.extend(SVG.Element,SVG.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)}}),SVG.extend(SVG.Rect,SVG.Ellipse,{radius:function(t,e){return this.attr({rx:t,ry:e||t})}}),SVG.Text&&SVG.extend(SVG.Text,SVG.FX,{font:function(t){for(var i in t)"anchor"==i?this.attr("text-anchor",t[i]):e.indexOf(i)>-1?this.attr("font-"+i,t[i]):this.attr(i,t[i]);return this}}),SVG.Set=function(){this.clear()},SVG.SetFX=function(t){this.set=t},SVG.extend(SVG.Set,{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 SVG.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}}),SVG.Set.inherit=function(){var t,e=[];for(var t in SVG.Shape.prototype)"function"==typeof SVG.Shape.prototype[t]&&"function"!=typeof SVG.Set.prototype[t]&&e.push(t);e.forEach(function(t){SVG.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 SVG.SetFX(this)):this}}),e=[];for(var t in SVG.FX.prototype)"function"==typeof SVG.FX.prototype[t]&&"function"!=typeof SVG.SetFX.prototype[t]&&e.push(t);e.forEach(function(t){SVG.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}})},SVG.extend(SVG.Container,{set:function(){return new SVG.Set}}),SVG.extend(SVG.Element,{data:function(t,e,i){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(2>arguments.length)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}}),SVG.extend(SVG.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 SVG}):"undefined"!=typeof exports&&(exports.SVG=SVG)}).call(this); \ No newline at end of file
+(function(){function t(t,e){return"number"==typeof t.from?t.from+(t.to-t.from)*e:t instanceof SVG.Color||t instanceof SVG.Number?t.at(e):1>e?t.from:t.to}if(this.SVG=function(t){return SVG.supported?(t=new SVG.Doc(t),SVG.parser||SVG.prepare(t),t):void 0},SVG.ns="http://www.w3.org/2000/svg",SVG.xmlns="http://www.w3.org/2000/xmlns/",SVG.xlink="http://www.w3.org/1999/xlink",SVG.did=1e3,SVG.eid=function(t){return"Svgjs"+t.charAt(0).toUpperCase()+t.slice(1)+SVG.did++},SVG.create=function(t){var e=document.createElementNS(this.ns,t);return e.setAttribute("id",this.eid(t)),e},SVG.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];SVG.Set&&SVG.Set.inherit&&SVG.Set.inherit()},SVG.get=function(t){var e=document.getElementById(t);return e?e.instance:void 0},SVG.prepare=function(t){var e=document.getElementsByTagName("body")[0],i=(e?new SVG.Doc(e):t.nested()).size(2,2);SVG.parser={body:e||t.parent,draw:i.style("opacity:0;position:fixed;left:100%;top:100%;overflow:hidden"),poly:i.polygon().node,path:i.path().node}},SVG.supported=function(){return!!document.createElementNS&&!!document.createElementNS(SVG.ns,"svg").createSVGRect}(),!SVG.supported)return!1;SVG.invent=function(t){var e="function"==typeof t.create?t.create:function(){this.constructor.call(this,SVG.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&SVG.extend(e,t.extend),t.construct&&SVG.extend(t.parent||SVG.Container,t.construct),e},SVG.regex={test:function(t,e){return this[e].test(t)},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:/[^:]+:[^;]+;?/,isStyle:/^font|text|leading|cursor/,isBlank:/^(\s+)?$/,isNumber:/^-?[\d\.]+$/,isPercent:/^-?[\d\.]+%$/},SVG.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"},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}}},SVG.Color=function(t){var e;this.r=0,this.g=0,this.b=0,"string"==typeof t?SVG.regex.isRgb.test(t)?(e=SVG.regex.rgb.exec(t.replace(/\s/g,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):SVG.regex.isHex.test(t)&&(e=SVG.regex.hex.exec(this._fullHex(t)),this.r=parseInt(e[1],16),this.g=parseInt(e[2],16),this.b=parseInt(e[3],16)):"object"==typeof t&&(this.r=t.r,this.g=t.g,this.b=t.b)},SVG.extend(SVG.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+this._compToHex(this.r)+this._compToHex(this.g)+this._compToHex(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return.3*(this.r/255)+.59*(this.g/255)+.11*(this.b/255)},morph:function(t){return this.destination=new SVG.Color(t),this},at:function(t){return this.destination?(t=0>t?0:t>1?1:t,new SVG.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},_fullHex:function(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},_compToHex:function(t){var e=t.toString(16);return 1==e.length?"0"+e:e}}),SVG.Color.test=function(t){return t+="",SVG.regex.isHex.test(t)||SVG.regex.isRgb.test(t)},SVG.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},SVG.Color.isColor=function(t){return SVG.Color.isRgb(t)||SVG.Color.test(t)},SVG.Array=function(t,e){t=(t||[]).valueOf(),0==t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},SVG.extend(SVG.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 SVG.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(" ")}}),SVG.PointArray=function(){this.constructor.apply(this,arguments)},SVG.PointArray.prototype=new SVG.Array,SVG.extend(SVG.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 SVG.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.x;return this},bbox:function(){return this._cachedBBox?this._cachedBBox:(SVG.parser.poly.setAttribute("points",this.toString()),SVG.parser.poly.getBBox())}}),SVG.PathArray=function(t,e){this.constructor.call(this,t,e)},SVG.PathArray.prototype=new SVG.Array,SVG.extend(SVG.PathArray,{toString:function(){for(var t,e=0,i=this.value.length,n=[];i>e;e++){switch(t=[this.value[e].type],this.value[e].type){case"H":t.push(this.value[e].x);break;case"V":t.push(this.value[e].y);break;case"M":case"L":case"T":case"S":case"Q":case"C":/[QC]/.test(this.value[e].type)&&t.push(this.value[e].x1,this.value[e].y1),/[CS]/.test(this.value[e].type)&&t.push(this.value[e].x2,this.value[e].y2),t.push(this.value[e].x,this.value[e].y);break;case"A":t.push(this.value[e].rx,this.value[e].ry,this.value[e].angle,this.value[e].largeArcFlag,this.value[e].sweepFlag,this.value[e].x,this.value[e].y)}n.push(t.join(" "))}return n.join(" ")},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--)switch(this.value[n].type){case"H":this.value[n].x+=t;break;case"V":this.value[n].y+=e;break;case"M":case"L":case"T":case"S":case"Q":case"C":this.value[n].x+=t,this.value[n].y+=e,/[CQ]/.test(this.value[n].type)&&(this.value[n].x1+=t,this.value[n].y1+=e),/[CS]/.test(this.value[n].type)&&(this.value[n].x2+=t,this.value[n].y2+=e);break;case"A":this.value[n].x+=t,this.value[n].y+=e}return this},size:function(t,e){for(var i=this.bbox(),n=this.value.length-1;n>=0;n--)switch(this.value[n].type){case"H":this.value[n].x=(this.value[n].x-i.x)*t/i.width+i.x;break;case"V":this.value[n].y=(this.value[n].y-i.y)*e/i.height+i.y;break;case"M":case"L":case"T":case"S":case"Q":case"C":this.value[n].x=(this.value[n].x-i.x)*t/i.width+i.x,this.value[n].y=(this.value[n].y-i.y)*e/i.height+i.y,/[CQ]/.test(this.value[n].type)&&(this.value[n].x1=(this.value[n].x1-i.x)*t/i.width+i.x,this.value[n].y1=(this.value[n].y1-i.y)*e/i.height+i.y),/[CS]/.test(this.value[n].type)&&(this.value[n].x2=(this.value[n].x2-i.x)*t/i.width+i.x,this.value[n].y2=(this.value[n].y2-i.y)*e/i.height+i.y);break;case"A":this.value[n].values.rx=this.value[n].values.rx*t/i.width,this.value[n].values.ry=this.value[n].values.ry*e/i.height,this.value[n].values.x=(this.value[n].values.x-i.x)*t/i.width+i.x,this.value[n].values.y=(this.value[n].values.y-i.y)*e/i.height+i.y}return this},parse:function(t){if(t=t.valueOf(),Array.isArray(t))return t;var e,i,n,r,s,h,o,a,u,l,c,f=0,p=0;for(SVG.parser.path.setAttribute("d",t),c=SVG.parser.path.pathSegList,e=0,i=c.numberOfItems;i>e;++e){if(l=c.getItem(e),u=l.pathSegTypeAsLetter,/[MLHVCSQTA]/.test(u))"x"in l&&(f=l.x),"y"in l&&(p=l.y);else switch("x1"in l&&(s=f+l.x1),"x2"in l&&(o=f+l.x2),"y1"in l&&(h=p+l.y1),"y2"in l&&(a=p+l.y2),"x"in l&&(f+=l.x),"y"in l&&(p+=l.y),u){case"m":c.replaceItem(SVG.parser.path.createSVGPathSegMovetoAbs(f,p),e);break;case"l":c.replaceItem(SVG.parser.path.createSVGPathSegLinetoAbs(f,p),e);break;case"h":c.replaceItem(SVG.parser.path.createSVGPathSegLinetoHorizontalAbs(f),e);break;case"v":c.replaceItem(SVG.parser.path.createSVGPathSegLinetoVerticalAbs(p),e);break;case"c":c.replaceItem(SVG.parser.path.createSVGPathSegCurvetoCubicAbs(f,p,s,h,o,a),e);break;case"s":c.replaceItem(SVG.parser.path.createSVGPathSegCurvetoCubicSmoothAbs(f,p,o,a),e);break;case"q":c.replaceItem(SVG.parser.path.createSVGPathSegCurvetoQuadraticAbs(f,p,s,h),e);break;case"t":c.replaceItem(SVG.parser.path.createSVGPathSegCurvetoQuadraticSmoothAbs(f,p),e);break;case"a":c.replaceItem(SVG.parser.path.createSVGPathSegArcAbs(f,p,l.r1,l.r2,l.angle,l.largeArcFlag,l.sweepFlag),e);break;case"z":case"Z":f=n,p=r}/[Mm]/.test(u)&&(n=f,r=p)}for(t=[],c=SVG.parser.path.pathSegList,e=0,i=c.numberOfItems;i>e;++e){switch(l=c.getItem(e),u={},l.pathSegTypeAsLetter){case"M":case"L":case"T":case"S":case"Q":case"C":/[QC]/.test(l.pathSegTypeAsLetter)&&(u.x1=l.x1,u.y1=l.y1),/[SC]/.test(l.pathSegTypeAsLetter)&&(u.x2=l.x2,u.y2=l.y2);break;case"A":u={r1:l.r1,r2:l.r2,a:l.angle,l:l.largeArcFlag,s:l.sweepFlag}}u.type=l.pathSegTypeAsLetter,u.x=l.x,u.y=l.y,t.push(u)}return t},bbox:function(){return this._cachedBBox?this._cachedBBox:(SVG.parser.path.setAttribute("d",this.toString()),SVG.parser.path.getBBox())}}),SVG.Number=function(t){switch(this.value=0,this.unit="",typeof t){case"number":this.value=isNaN(t)?0:isFinite(t)?t:0>t?-3.4e38:3.4e38;break;case"string":var e=t.match(SVG.regex.unit);e&&(this.value=parseFloat(e[1]),"%"==e[2]&&(this.value/=100),this.unit=e[2]);break;default:t instanceof SVG.Number&&(this.value=t.value,this.unit=t.unit)}},SVG.extend(SVG.Number,{toString:function(){return("%"==this.unit?~~(1e8*this.value)/1e6:this.value)+this.unit},valueOf:function(){return this.value},plus:function(t){return this.value=this+new SVG.Number(t),this},minus:function(t){return this.plus(-new SVG.Number(t))},times:function(t){return this.value=this*new SVG.Number(t),this},divide:function(t){return this.value=this/new SVG.Number(t),this},to:function(t){return"string"==typeof t&&(this.unit=t),this},morph:function(t){return this.destination=new SVG.Number(t),this},at:function(t){return this.destination?new SVG.Number(this.destination).minus(this).times(t).plus(this):this}}),SVG.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 SVG.Number(t.width()),r=new SVG.Number(t.height());"%"==n.unit;)s*=n.value,n=new SVG.Number(t instanceof SVG.Doc?t.parent.offsetWidth:t.width());for(;"%"==r.unit;)h*=r.value,r=new SVG.Number(t instanceof SVG.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)},SVG.extend(SVG.ViewBox,{toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height}}),SVG.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}this.cx=this.x+this.width/2,this.cy=this.y+this.height/2},SVG.extend(SVG.BBox,{merge:function(t){var e=new SVG.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,e.cx=e.x+e.width/2,e.cy=e.y+e.height/2,e}}),SVG.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.cx=this.x+this.width/2,this.cy=this.y+this.height/2},SVG.extend(SVG.RBox,{merge:function(t){var e=new SVG.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,e.cx=e.x+e.width/2,e.cy=e.y+e.height/2,e}}),SVG.Element=SVG.invent({create:function(t){this._stroke=SVG.defaults.attrs.stroke,this.styles={},this.trans=SVG.defaults.trans(),(this.node=t)&&(this.type=t.nodeName,this.node.instance=this)},extend:{x:function(t){return t&&(t=new SVG.Number(t),t.value/=this.trans.scaleX),this.attr("x",t)},y:function(t){return t&&(t=new SVG.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=this._proportionalSize(t,e);return this.attr({width:new SVG.Number(i.width),height:new SVG.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||SVG.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]=SVG.regex.test(e[i].nodeValue,"isNumber")?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 this._isStyle(t)?"text"==t?this.content:"leading"==t&&this.leading?this.leading():this.style(t):(e=this.node.getAttribute(t),null==e?SVG.defaults.attrs[t]:SVG.regex.test(e,"isNumber")?parseFloat(e):e);if("style"==t)return this.style(e);if("x"==t&&Array.isArray(this.lines))for(i=this.lines.length-1;i>=0;i--)this.lines[i].attr(t,e);"stroke-width"==t?this.attr("stroke",parseFloat(e)>0?this._stroke:null):"stroke"==t&&(this._stroke=e),SVG.Color.test(e)||SVG.Color.isRgb(e)?e=new SVG.Color(e):"number"==typeof e?e=new SVG.Number(e):Array.isArray(e)&&(e=new SVG.Array(e)),null!=i?this.node.setAttributeNS(i,t,e.toString()):this.node.setAttribute(t,e.toString()),this._isStyle(t)&&("text"==t?this.text(e):"leading"==t&&this.leading?this.leading(e):this.style(t,e),this.rebuild&&this.rebuild(t,e))}return this},transform:function(t,e){if(0==arguments.length)return this.trans;if("string"==typeof t){if(2>arguments.length)return this.trans[t];var i={};return i[t]=e,this.transform(i)}var i=[];t=this._parseMatrix(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!=SVG.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 SVG.Number(t.x/t.scaleX)+" "+new SVG.Number(t.y/t.scaleY)+")"),0==i.length?this.node.removeAttribute("transform"):this.node.setAttribute("transform",i.join(" ")),this},style:function(t,e){if(0==arguments.length)return this.attr("style")||"";if(2>arguments.length)if("object"==typeof t)for(e in t)this.style(e,t[e]);else{if(!SVG.regex.isCss.test(t))return this.styles[t];t=t.split(";");for(var i=0;t.length>i;i++)e=t[i].split(":"),2==e.length&&this.style(e[0].replace(/\s+/g,""),e[1].replace(/^\s+/,"").replace(/\s+$/,""))}else null===e||SVG.regex.test(e,"isBlank")?delete this.styles[t]:this.styles[t]=e;t="";for(e in this.styles)t+=e+":"+this.styles[e]+";";return""==t?this.node.removeAttribute("style"):this.node.setAttribute("style",t),this},bbox:function(){return new SVG.BBox(this)},rbox:function(){return new SVG.RBox(this)},inside:function(t,e){var i=this.bbox();return t>i.x&&e>i.y&&i.x+i.width>t&&i.y+i.height>e},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")},_parent:function(t){for(var e=this;null!=e&&!(e instanceof t);)e=e.parent;return e},_isStyle:function(t){return"string"==typeof t?SVG.regex.test(t,"isStyle"):!1},_parseMatrix:function(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},_proportionalSize:function(t,e){if(null==t||null==e){var i=this.bbox();null==e?e=i.height/i.width*t:null==t&&(t=i.width/i.height*e)}return{width:t,height:e}}}}),SVG.Parent=SVG.invent({create:function(t){this.constructor.call(this,t)},inherit:SVG.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 SVG.Element&&t.apply(r[i],[i,r]),e&&r[i]instanceof SVG.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()}}}),SVG.Container=SVG.invent({create:function(t){this.constructor.call(this,t)},inherit:SVG.Parent,extend:{viewbox:function(t){return 0==arguments.length?new SVG.ViewBox(this):(t=1==arguments.length?[t.x,t.y,t.width,t.height]:[].slice.call(arguments),this.attr("viewBox",t))}}}),SVG.FX=function(t){this.target=t},SVG.extend(SVG.FX,{animate:function(e,i,n){var r,s,h,o,a=this.target,u=this;return"object"==typeof e&&(n=e.delay,i=e.ease,e=e.duration),e=null==e?1e3:e,i=i||"<>",u.to=function(e){var n;if(e=0>e?0:e>1?1:e,null==r){r=[];for(o in u.attrs)r.push(o);if(a.morphArray&&(u._plot||r.indexOf("points")>-1)){var l,c=new a.morphArray(u._plot||u.attrs.points||a.array);u._size&&c.size(u._size.width.to,u._size.height.to),l=c.bbox(),u._x?c.move(u._x.to,l.y):u._cx&&c.move(u._cx.to-l.width/2,l.y),l=c.bbox(),u._y?c.move(l.x,u._y.to):u._cy&&c.move(l.x,u._cy.to-l.height/2),delete u._x,delete u._y,delete u._cx,delete u._cy,delete u._size,u._plot=a.array.morph(c)}}if(null==s){s=[];for(o in u.trans)s.push(o)}if(null==h){h=[];for(o in u.styles)h.push(o)}for(e="<>"==i?-Math.cos(e*Math.PI)/2+.5:">"==i?Math.sin(e*Math.PI/2):"<"==i?-Math.cos(e*Math.PI/2)+1:"-"==i?e:"function"==typeof i?i(e):e,u._plot?a.plot(u._plot.at(e)):(u._x?a.x(t(u._x,e)):u._cx&&a.cx(t(u._cx,e)),u._y?a.y(t(u._y,e)):u._cy&&a.cy(t(u._cy,e)),u._size&&a.size(t(u._size.width,e),t(u._size.height,e))),u._viewbox&&a.viewbox(t(u._viewbox.x,e),t(u._viewbox.y,e),t(u._viewbox.width,e),t(u._viewbox.height,e)),n=r.length-1;n>=0;n--)a.attr(r[n],t(u.attrs[r[n]],e));for(n=s.length-1;n>=0;n--)a.transform(s[n],t(u.trans[s[n]],e));for(n=h.length-1;n>=0;n--)a.style(h[n],t(u.styles[h[n]],e));u._during&&u._during.call(a,e,function(i,n){return t({from:i,to:n},e)})},"number"==typeof e&&(this.timeout=setTimeout(function(){var t=(new Date).getTime();u.situation={interval:1e3/60,start:t,play:!0,finish:t+e,duration:e},u.render=function(){if(u.situation.play===!0){var t=(new Date).getTime(),r=t>u.situation.finish?1:(t-u.situation.start)/e;u.to(r),t>u.situation.finish?(u._plot&&a.plot(new SVG.PointArray(u._plot.destination).settle()),u._loop===!0||"number"==typeof u._loop&&u._loop>1?("number"==typeof u._loop&&--u._loop,u.animate(e,i,n)):u._after?u._after.apply(a,[u]):u.stop()):requestAnimFrame(u.render)}else requestAnimFrame(u.render)},u.render()},n||0)),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]=SVG.Color.isColor(n)?new SVG.Color(n).morph(e):SVG.regex.unit.test(n)?new SVG.Number(n).morph(e):{from:n,to:e}}return this},transform:function(t,e){if(1==arguments.length){t=this.target._parseMatrix(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={from:this.target.x(),to:t},this},y:function(t){return this._y={from:this.target.y(),to:t},this},cx:function(t){return this._cx={from:this.target.cx(),to:t},this},cy:function(t){return this._cy={from:this.target.cy(),to: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 SVG.Text)this.attr("font-size",t);else{var i=this.target.bbox();this._size={width:{from:i.width,to:t},height:{from:i.height,to:e}}}return this},plot:function(t){return this._plot=t,this},viewbox:function(t,e,i,n){if(this.target instanceof SVG.Container){var r=this.target.viewbox();this._viewbox={x:{from:r.x,to:t},y:{from:r.y,to:e},width:{from:r.width,to:i},height:{from:r.height,to:n}}}return this},update:function(t){return this.target instanceof SVG.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 SVG.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(){return clearTimeout(this.timeout),clearInterval(this.interval),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._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}}),SVG.extend(SVG.Element,{animate:function(t,e,i){return(this.fx||(this.fx=new SVG.FX(this))).stop().animate(t,e,i)},stop:function(){return this.fx&&this.fx.stop(),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this}}),window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)}}(),SVG.extend(SVG.Element,SVG.FX,{relative:function(){var t,e=this;return{x:function(i){return t=e.bbox(),e.x(t.x+(i||0))},y:function(i){return t=e.bbox(),e.y(t.y+(i||0))},move:function(t,e){return this.x(t),this.y(e)}}}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave"].forEach(function(t){SVG.Element.prototype[t]=function(e){var i=this;return this.node["on"+t]="function"==typeof e?function(){return e.apply(i,arguments)}:null,this}}),SVG.on=function(t,e,i){t.addEventListener?t.addEventListener(e,i,!1):t.attachEvent("on"+e,i)},SVG.off=function(t,e,i){t.removeEventListener?t.removeEventListener(e,i,!1):t.detachEvent("on"+e,i)},SVG.extend(SVG.Element,{on:function(t,e){return SVG.on(this.node,t,e),this},off:function(t,e){return SVG.off(this.node,t,e),this}}),SVG.Defs=SVG.invent({create:"defs",inherit:SVG.Container}),SVG.G=SVG.invent({create:"g",inherit:SVG.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 SVG.G)}}}),SVG.extend(SVG.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}}),SVG.Mask=SVG.invent({create:function(){this.constructor.call(this,SVG.create("mask")),this.targets=[]},inherit:SVG.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 SVG.Mask)}}}),SVG.extend(SVG.Element,{maskWith:function(t){return this.masker=t instanceof SVG.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)}}),SVG.Clip=SVG.invent({create:function(){this.constructor.call(this,SVG.create("clipPath")),this.targets=[]},inherit:SVG.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 SVG.Clip)}}}),SVG.extend(SVG.Element,{clipWith:function(t){return this.clipper=t instanceof SVG.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)}}),SVG.Gradient=SVG.invent({create:function(t){this.constructor.call(this,SVG.create(t+"Gradient")),this.type=t},inherit:SVG.Container,extend:{from:function(t,e){return"radial"==this.type?this.attr({fx:new SVG.Number(t),fy:new SVG.Number(e)}):this.attr({x1:new SVG.Number(t),y1:new SVG.Number(e)})},to:function(t,e){return"radial"==this.type?this.attr({cx:new SVG.Number(t),cy:new SVG.Number(e)}):this.attr({x2:new SVG.Number(t),y2:new SVG.Number(e)})},radius:function(t){return"radial"==this.type?this.attr({r:new SVG.Number(t)}):this},at:function(t){return this.put((new SVG.Stop).update(t))},update:function(t){return this.clear(),t(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)}}}),SVG.extend(SVG.Defs,{gradient:function(t,e){var i=this.put(new SVG.Gradient(t));return e(i),i}}),SVG.Stop=SVG.invent({create:"stop",inherit:SVG.Element,extend:{update:function(t){return 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 SVG.Number(t.offset)),this}}}),SVG.Doc=SVG.invent({create:function(t){this.parent="string"==typeof t?document.getElementById(t):t,this.constructor.call(this,"svg"==this.parent.nodeName?this.parent:SVG.create("svg")),this.attr({xmlns:SVG.ns,version:"1.1",width:"100%",height:"100%"}).attr("xmlns:xlink",SVG.xlink,SVG.xmlns),this._defs=new SVG.Defs,this._defs.parent=this,this.node.appendChild(this._defs.node),this.doSubPixelOffsetFix=!1,"svg"!=this.parent.nodeName&&this.stage()},inherit:SVG.Container,extend:{stage:function(){var t,e=this,i=document.createElement("div");return i.style.cssText="position:relative;height:100%;",e.parent.appendChild(i),i.appendChild(e.node),t=function(){"complete"===document.readyState?(e.style("position:absolute;"),setTimeout(function(){e.style("position:relative;overflow:hidden;"),e.parent.removeChild(e.node.parentNode),e.node.parentNode.removeChild(e.node),e.parent.appendChild(e.node),e.subPixelOffsetFix(),SVG.on(window,"resize",function(){e.subPixelOffsetFix()})},5)):setTimeout(t,10)},t(),this},defs:function(){return this._defs},subPixelOffsetFix:function(){if(this.doSubPixelOffsetFix){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.doSubPixelOffsetFix=!0,this}}}),SVG.Shape=SVG.invent({create:function(t){this.constructor.call(this,t)},inherit:SVG.Element}),SVG.Use=SVG.invent({create:"use",inherit:SVG.Shape,extend:{element:function(t){return this.target=t,this.attr("href","#"+t,SVG.xlink)}},construct:{use:function(t){return this.put(new SVG.Use).element(t)}}}),SVG.Rect=SVG.invent({create:"rect",inherit:SVG.Shape,construct:{rect:function(t,e){return this.put((new SVG.Rect).size(t,e))}}}),SVG.Ellipse=SVG.invent({create:"ellipse",inherit:SVG.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 SVG.Number(t).divide(this.trans.scaleX))},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",new SVG.Number(t).divide(this.trans.scaleY))},width:function(t){return null==t?2*this.attr("rx"):this.attr("rx",new SVG.Number(t).divide(2))},height:function(t){return null==t?2*this.attr("ry"):this.attr("ry",new SVG.Number(t).divide(2))},size:function(t,e){var i=this._proportionalSize(t,e);return this.attr({rx:new SVG.Number(i.width).divide(2),ry:new SVG.Number(i.height).divide(2)})}},construct:{circle:function(t){return this.ellipse(t,t)},ellipse:function(t,e){return this.put(new SVG.Ellipse).size(t,e).move(0,0)}}}),SVG.Line=SVG.invent({create:"line",inherit:SVG.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=this._proportionalSize(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 SVG.Line).plot(t,e,i,n))}}}),SVG.Polyline=SVG.invent({create:"polyline",inherit:SVG.Shape,construct:{polyline:function(t){return this.put(new SVG.Polyline).plot(t)}}}),SVG.Polygon=SVG.invent({create:"polygon",inherit:SVG.Shape,construct:{polygon:function(t){return this.put(new SVG.Polygon).plot(t)}}}),SVG.extend(SVG.Polyline,SVG.Polygon,{morphArray:SVG.PointArray,plot:function(t){return this.attr("points",this.array=new SVG.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=this._proportionalSize(t,e);return this.attr("points",this.array.size(i.width,i.height))}}),SVG.Path=SVG.invent({create:"path",inherit:SVG.Shape,extend:{plot:function(t){return this.attr("d",this.array=new SVG.PathArray(t,[{type:"M",x:0,y: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=this._proportionalSize(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 SVG.Path).plot(t)}}}),SVG.Image=SVG.invent({create:"image",inherit:SVG.Shape,extend:{load:function(t){return t?this.attr("href",this.src=t,SVG.xlink):this}},construct:{image:function(t,e,i){return e=null!=e?e:100,this.put((new SVG.Image).load(t).size(e,null!=i?i:e))}}});var e="size family weight stretch variant style".split(" ");SVG.Text=SVG.invent({create:function(){this.constructor.call(this,SVG.create("text")),this.styles={"font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"},this._leading=new SVG.Number("1.2em"),this._rebuild=!0},inherit:SVG.Shape,extend:{x:function(t,e){return null==t?e?this.attr("x"):this.bbox().x:(e||(e=this.style("text-anchor"),t="start"==e?t:"end"==e?t+this.bbox().width:t+this.bbox().width/2),this.textPath||this.lines.each(function(){this.newLined&&this.x(t)}),this.attr("x",t))},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t,e){return null==t?this.bbox().cy:this.y(e?t:t-this.bbox().height/2)},move:function(t,e,i){return this.x(t,i).y(e)},center:function(t,e,i){return this.cx(t,i).cy(e,i)},text:function(t){if(null==t)return this.content;if(this.clear(),"function"==typeof t)this._rebuild=!1,t.call(this,this);else{this._rebuild=!0,t=SVG.regex.isBlank.test(t)?"text":t;var e,i,n=t.split("\n");for(e=0,i=n.length;i>e;e++)this.tspan(n[e]).newLine();this.rebuild()}return this},tspan:function(t){var e=this.textPath?this.textPath.node:this.node,i=(new SVG.TSpan).text(t),n=this.style();return e.appendChild(i.node),this.lines.add(i),SVG.regex.isBlank.test(n)||i.style(n),this.content+=t,i.parent=this,i},size:function(t){return this.attr("font-size",t)},leading:function(t){return null==t?this._leading:(t=new SVG.Number(t),this._leading=t,this.lines.each(function(){this.newLined&&this.attr("dy",t)}),this)},rebuild:function(){return this._rebuild&&this.lines.attr({x:this.attr("x"),dy:this._leading,style:this.style()}),this},clear:function(){for(var t=this.textPath?this.textPath.node:this.node;t.hasChildNodes();)t.removeChild(t.lastChild);return delete this.lines,this.lines=new SVG.Set,this.content="",this}},construct:{text:function(t){return this.put(new SVG.Text).text(t)}}}),SVG.TSpan=SVG.invent({create:"tspan",inherit:SVG.Shape,extend:{text:function(t){return this.node.appendChild(document.createTextNode(t)),this},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){return this.newLined=!0,this.parent.content+="\n",this.dy(this.parent._leading),this.attr("x",this.parent.x())}}}),SVG.TextPath=SVG.invent({create:"textPath",inherit:SVG.Element,parent:SVG.Text,construct:{path:function(t){for(this.textPath=new SVG.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,!0),this.textPath.parent=this,this.textPath.attr("href","#"+this.track,SVG.xlink),this},plot:function(t){return this.track&&this.track.plot(t),this}}}),SVG.Nested=SVG.invent({create:function(){this.constructor.call(this,SVG.create("svg")),this.style("overflow","visible")},inherit:SVG.Container,construct:{nested:function(){return this.put(new SVG.Nested)}}}),SVG.A=SVG.invent({create:"a",inherit:SVG.Container,extend:{to:function(t){return this.attr("href",t,SVG.xlink)},show:function(t){return this.attr("show",t,SVG.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new SVG.A).to(t)}}}),SVG.extend(SVG.Element,{linkTo:function(t){var e=new SVG.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent.put(e).put(this)}}),SVG._stroke=["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],SVG._fill=["color","opacity","rule"];var i=function(t,e){return"color"==e?t:t+"-"+e};["fill","stroke"].forEach(function(t){var e={};e[t]=function(e){if("string"==typeof e||SVG.Color.isRgb(e)||e&&"function"==typeof e.fill)this.attr(t,e);else for(index=SVG["_"+t].length-1;index>=0;index--)null!=e[SVG["_"+t][index]]&&this.attr(i(t,SVG["_"+t][index]),e[SVG["_"+t][index]]);return this},SVG.extend(SVG.Element,SVG.FX,e)}),SVG.extend(SVG.Element,SVG.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)}}),SVG.extend(SVG.Rect,SVG.Ellipse,{radius:function(t,e){return this.attr({rx:t,ry:e||t})}}),SVG.Text&&SVG.extend(SVG.Text,SVG.FX,{font:function(t){for(var i in t)"anchor"==i?this.attr("text-anchor",t[i]):e.indexOf(i)>-1?this.attr("font-"+i,t[i]):this.attr(i,t[i]);return this}}),SVG.Set=SVG.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 SVG.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 SVG.Set}}}),SVG.SetFX=SVG.invent({create:function(t){this.set=t}}),SVG.Set.inherit=function(){var t,e=[];for(var t in SVG.Shape.prototype)"function"==typeof SVG.Shape.prototype[t]&&"function"!=typeof SVG.Set.prototype[t]&&e.push(t);e.forEach(function(t){SVG.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 SVG.SetFX(this)):this}}),e=[];for(var t in SVG.FX.prototype)"function"==typeof SVG.FX.prototype[t]&&"function"!=typeof SVG.SetFX.prototype[t]&&e.push(t);e.forEach(function(t){SVG.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}})},SVG.extend(SVG.Element,{data:function(t,e,i){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(2>arguments.length)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}}),SVG.extend(SVG.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 SVG}):"undefined"!=typeof exports&&(exports.SVG=SVG)}).call(this); \ No newline at end of file