aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/svg.js10396
-rw-r--r--dist/svg.min.js4
-rw-r--r--gulpfile.js175
-rw-r--r--package-lock.json9169
-rw-r--r--package.json1
-rw-r--r--src/HtmlNode.js21
-rw-r--r--src/arrange.js74
-rw-r--r--src/array.js65
-rw-r--r--src/attr.js70
-rw-r--r--src/bare.js27
-rw-r--r--src/boxes.js99
-rw-r--r--src/clip.js38
-rw-r--r--src/color.js101
-rw-r--r--src/container.js11
-rw-r--r--src/css.js23
-rw-r--r--src/data.js26
-rw-r--r--src/default.js68
-rw-r--r--src/defs.js4
-rw-r--r--src/doc.js39
-rw-r--r--src/element.js245
-rw-r--r--src/ellipse.js80
-rw-r--r--src/event.js124
-rw-r--r--src/flatten.js12
-rw-r--r--src/fx.js536
-rw-r--r--src/gradient.js95
-rw-r--r--src/group.js41
-rw-r--r--src/helpers.js115
-rw-r--r--src/hyperlink.js35
-rw-r--r--src/image.js38
-rw-r--r--src/line.js42
-rw-r--r--src/marker.js62
-rw-r--r--src/mask.js33
-rw-r--r--src/matrix.js143
-rw-r--r--src/memory.js43
-rw-r--r--src/nested.js13
-rw-r--r--src/number.js72
-rw-r--r--src/parent.js72
-rw-r--r--src/parser.js15
-rw-r--r--src/path.js58
-rw-r--r--src/patharray.js188
-rw-r--r--src/pattern.js53
-rw-r--r--src/point.js48
-rw-r--r--src/pointarray.js85
-rw-r--r--src/pointed.js20
-rw-r--r--src/poly.js52
-rw-r--r--src/rect.js13
-rw-r--r--src/regex.js38
-rw-r--r--src/selector.js16
-rw-r--r--src/shape.js10
-rw-r--r--src/sugar.js101
-rw-r--r--src/svg.js73
-rw-r--r--src/symbol.js11
-rw-r--r--src/text.js151
-rw-r--r--src/textpath.js42
-rw-r--r--src/transform.js258
-rw-r--r--src/umd.js10
-rw-r--r--src/use.js21
-rw-r--r--src/utilities.js37
58 files changed, 16558 insertions, 6954 deletions
diff --git a/dist/svg.js b/dist/svg.js
index d61e04e..26ddbc7 100644
--- a/dist/svg.js
+++ b/dist/svg.js
@@ -6,5174 +6,5262 @@
* @copyright Wout Fierens <wout@mick-wout.com>
* @license MIT
*
-* BUILT: Wed Feb 07 2018 10:08:55 GMT+0100 (Mitteleuropäische Zeit)
+* BUILT: Tue Feb 27 2018 03:37:50 GMT+1100 (AEDT)
*/;
-(function(root, factory) {
- /* istanbul ignore next */
- if (typeof define === 'function' && define.amd) {
- define(function(){
- return factory(root, root.document)
- })
- } else if (typeof exports === 'object') {
- module.exports = root.document ? factory(root, root.document) : function(w){ return factory(w, w.document) }
- } else {
- root.SVG = factory(root, root.document)
- }
-}(typeof window !== "undefined" ? window : this, function(window, document) {
-
-// The main wrapping element
-var SVG = this.SVG = function(element) {
- if (SVG.supported) {
- element = createElement(element)
-
- return element
- }
-}
-
-// Default namespaces
-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.svgjs = 'http://svgjs.com/svgjs'
-
-// Svg support test
-SVG.supported = (function() {
- return !! document.createElementNS &&
- !! document.createElementNS(SVG.ns,'svg').createSVGRect
-})()
-
-// Don't bother to continue if SVG is not supported
-if (!SVG.supported) return false
-
-// Element id sequence
-SVG.did = 1000
-
-// Get next named element id
-SVG.eid = function(name) {
- return 'Svgjs' + capitalize(name) + (SVG.did++)
-}
-
-// Method for element creation
-SVG.create = function(name) {
- // create element
- return document.createElementNS(this.ns, name)
-}
-
-// Method for extending objects
-SVG.extend = function(modules, methods) {
- var key, i
-
- modules = Array.isArray(modules) ? modules : [modules]
-
- for (i = modules.length - 1; i >= 0; i--)
- if (modules[i])
- for (key in methods)
- modules[i].prototype[key] = methods[key]
-}
-
-// Invent new element
-SVG.invent = function(config) {
- // Create element initializer
- var initializer = typeof config.create == 'function' ?
- config.create :
- function(node) {
- this.constructor.call(this, node || 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
-}
-
-// Adopt existing svg elements
-SVG.adopt = function(node) {
- // check for presence of node
- if (!node) return null
-
- // make sure a node isn't already adopted
- if (node.instance) return node.instance
-
- if(!(node instanceof window.SVGElement))
- return new SVG.HtmlNode(node)
-
- // initialize variables
- var element
-
- // adopt with element-specific settings
- if (node.nodeName == 'svg')
- element = node.parentNode instanceof window.SVGElement ? new SVG.Nested(node) : new SVG.Doc(node)
- else if (node.nodeName == 'linearGradient' || node.nodeName == 'radialGradient')
- element = new SVG.Gradient(node)
- else if (SVG[capitalize(node.nodeName)])
- element = new SVG[capitalize(node.nodeName)](node)
- else
- element = new SVG.Parent(node)
-
- return element
-}
-
-// Storage for regular expressions
-SVG.regex = {
- // Parse unit value
- numberAndUnit: /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i
-
- // Parse hex value
-, hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i
-
- // Parse rgb value
-, rgb: /rgb\((\d+),(\d+),(\d+)\)/
-
- // Parse reference id
-, reference: /#([a-z0-9\-_]+)/i
-
- // splits a transformation chain
-, transforms: /\)\s*,?\s*/
-
- // Whitespace
-, whitespace: /\s/g
-
- // Test hex value
-, isHex: /^#[a-f0-9]{3,6}$/i
-
- // Test rgb value
-, isRgb: /^rgb\(/
-
- // Test css declaration
-, isCss: /[^:]+:[^;]+;?/
-
- // Test for blank string
-, isBlank: /^(\s+)?$/
-
- // Test for numeric string
-, isNumber: /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i
-
- // Test for percent value
-, isPercent: /^-?[\d\.]+%$/
-
- // Test for image url
-, isImage: /\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i
-
- // split at whitespace and comma
-, delimiter: /[\s,]+/
-
- // The following regex are used to parse the d attribute of a path
-
- // Matches all hyphens which are not after an exponent
-, hyphen: /([^e])\-/gi
-
- // Replaces and tests for all path letters
-, pathLetters: /[MLHVCSQTAZ]/gi
-
- // yes we need this one, too
-, isPathLetter: /[MLHVCSQTAZ]/i
-
- // matches 0.154.23.45
-, numbersWithDots: /((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi
-
- // matches .
-, dots: /\./g
-}
-
-SVG.utils = {
- // Map function
- map: function(array, block) {
- var i
- , il = array.length
- , result = []
-
- for (i = 0; i < il; i++)
- result.push(block(array[i]))
-
- return result
- }
-
- // Filter function
-, filter: function(array, block) {
- var i
- , il = array.length
- , result = []
-
- for (i = 0; i < il; i++)
- if (block(array[i]))
- result.push(array[i])
-
- return result
- }
-
- // Degrees to radians
-, radians: function(d) {
- return d % 360 * Math.PI / 180
- }
-
- // Radians to degrees
-, degrees: function(r) {
- return r * 180 / Math.PI % 360
- }
-
-, filterSVGElements: function(nodes) {
- return this.filter( nodes, function(el) { return el instanceof window.SVGElement })
- }
-
+
+(function(root, factory) {
+ /* istanbul ignore next */
+ if (typeof define === 'function' && define.amd) {
+ define(function(){
+ return factory(root, root.document)
+ })
+ } else if (typeof exports === 'object') {
+ module.exports = root.document ? factory(root, root.document) : function(w){ return factory(w, w.document) }
+ } else {
+ root.SVG = factory(root, root.document)
+ }
+}(typeof window !== "undefined" ? window : this, function(window, document) {
+
+// Check that our browser supports svg
+var supported = !! document.createElementNS &&
+ !! document.createElementNS('http://www.w3.org/2000/svg','svg').createSVGRect
+
+// If we don't support svg, just exit without doing anything
+if (!supported)
+ return {supported: false}
+
+// Otherwise, the library will be here
+/* global createElement, capitalize */
+/* eslint-disable new-cap */
+
+// The main wrapping element
+var SVG = this.SVG = function (element) {
+ if (SVG.supported) {
+ element = createElement(element)
+ return element
+ }
+}
+
+// Svg must be supported if we reached this stage
+SVG.supported = true
+
+// Default namespaces
+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.svgjs = 'http://svgjs.com/svgjs'
+
+// Element id sequence
+SVG.did = 1000
+
+// Get next named element id
+SVG.eid = function (name) {
+ return 'Svgjs' + capitalize(name) + (SVG.did++)
+}
+
+// Method for element creation
+SVG.create = function (name) {
+ // create element
+ return document.createElementNS(this.ns, name)
+}
+
+// Method for extending objects
+SVG.extend = function (modules, methods) {
+ var key, i
+
+ modules = Array.isArray(modules) ? modules : [modules]
+
+ for (i = modules.length - 1; i >= 0; i--) {
+ if (modules[i]) {
+ for (key in methods) {
+ modules[i].prototype[key] = methods[key]
+ }
+ }
+ }
}
-
-SVG.defaults = {
- // Default attribute values
- attrs: {
- // fill and stroke
- 'fill-opacity': 1
- , 'stroke-opacity': 1
- , 'stroke-width': 0
- , 'stroke-linejoin': 'miter'
- , 'stroke-linecap': 'butt'
- , fill: '#000000'
- , stroke: '#000000'
- , opacity: 1
- // position
- , x: 0
- , y: 0
- , cx: 0
- , cy: 0
- // size
- , width: 0
- , height: 0
- // radius
- , r: 0
- , rx: 0
- , ry: 0
- // gradient
- , offset: 0
- , 'stop-opacity': 1
- , 'stop-color': '#000000'
- // text
- , 'font-size': 16
- , 'font-family': 'Helvetica, Arial, sans-serif'
- , 'text-anchor': 'start'
- }
-
+
+// Invent new element
+SVG.invent = function (config) {
+ // Create element initializer
+ var initializer = typeof config.create === 'function' ? config.create
+ : function (node) {
+ this.constructor(node || 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
}
-// Module for color convertions
-SVG.Color = function(color) {
- var match
-
- // initialize defaults
- this.r = 0
- this.g = 0
- this.b = 0
-
- if(!color) return
-
- // parse color
- if (typeof color === 'string') {
- if (SVG.regex.isRgb.test(color)) {
- // get rgb values
- match = SVG.regex.rgb.exec(color.replace(SVG.regex.whitespace,''))
-
- // parse numeric values
- this.r = parseInt(match[1])
- this.g = parseInt(match[2])
- this.b = parseInt(match[3])
-
- } else if (SVG.regex.isHex.test(color)) {
- // get hex values
- match = SVG.regex.hex.exec(fullHex(color))
-
- // parse numeric values
- this.r = parseInt(match[1], 16)
- this.g = parseInt(match[2], 16)
- this.b = parseInt(match[3], 16)
-
- }
-
- } else if (typeof color === 'object') {
- this.r = color.r
- this.g = color.g
- this.b = color.b
-
- }
-
-}
-
-SVG.extend(SVG.Color, {
- // Default to hex conversion
- toString: function() {
- return this.toHex()
- }
- // Build hex value
-, toHex: function() {
- return '#'
- + compToHex(this.r)
- + compToHex(this.g)
- + compToHex(this.b)
- }
- // Build rgb value
-, toRgb: function() {
- return 'rgb(' + [this.r, this.g, this.b].join() + ')'
- }
- // Calculate true brightness
-, brightness: function() {
- return (this.r / 255 * 0.30)
- + (this.g / 255 * 0.59)
- + (this.b / 255 * 0.11)
- }
- // Make color morphable
-, morph: function(color) {
- this.destination = new SVG.Color(color)
-
- return this
- }
- // Get morphed color at given position
-, at: function(pos) {
- // make sure a destination is defined
- if (!this.destination) return this
-
- // normalise pos
- pos = pos < 0 ? 0 : pos > 1 ? 1 : pos
-
- // generate morphed color
- return new SVG.Color({
- r: ~~(this.r + (this.destination.r - this.r) * pos)
- , g: ~~(this.g + (this.destination.g - this.g) * pos)
- , b: ~~(this.b + (this.destination.b - this.b) * pos)
- })
- }
-
-})
-
-// Testers
-
-// Test if given value is a color string
-SVG.Color.test = function(color) {
- color += ''
- return SVG.regex.isHex.test(color)
- || SVG.regex.isRgb.test(color)
-}
-
-// Test if given value is a rgb object
-SVG.Color.isRgb = function(color) {
- return color && typeof color.r == 'number'
- && typeof color.g == 'number'
- && typeof color.b == 'number'
-}
-
-// Test if given value is a color
-SVG.Color.isColor = function(color) {
- return SVG.Color.isRgb(color) || SVG.Color.test(color)
+
+// Adopt existing svg elements
+SVG.adopt = function (node) {
+ // check for presence of node
+ if (!node) return null
+
+ // make sure a node isn't already adopted
+ if (node.instance) return node.instance
+
+ if (!(node instanceof window.SVGElement)) {
+ return new SVG.HtmlNode(node)
+ }
+
+ // initialize variables
+ var element
+
+ // adopt with element-specific settings
+ if (node.nodeName === 'svg') {
+ element = node.parentNode instanceof window.SVGElement ? new SVG.Nested(node) : new SVG.Doc(node)
+ } else if (node.nodeName === 'linearGradient' || node.nodeName === 'radialGradient') {
+ element = new SVG.Gradient(node)
+ } else if (SVG[capitalize(node.nodeName)]) {
+ element = new SVG[capitalize(node.nodeName)](node)
+ } else { element = new SVG.Parent(node) }
+
+ return element
}
-// Module for array conversion
-SVG.Array = function(array, fallback) {
- array = (array || []).valueOf()
-
- // if array is empty and fallback is provided, use fallback
- if (array.length == 0 && fallback)
- array = fallback.valueOf()
-
- // parse array
- this.value = this.parse(array)
-}
-
-SVG.extend(SVG.Array, {
- // Make array morphable
- morph: function(array) {
- this.destination = this.parse(array)
-
- // normalize length of arrays
- if (this.value.length != this.destination.length) {
- var lastValue = this.value[this.value.length - 1]
- , lastDestination = this.destination[this.destination.length - 1]
-
- while(this.value.length > this.destination.length)
- this.destination.push(lastDestination)
- while(this.value.length < this.destination.length)
- this.value.push(lastValue)
- }
-
- return this
- }
- // Clean up any duplicate points
-, settle: function() {
- // find all unique values
- for (var i = 0, il = this.value.length, seen = []; i < il; i++)
- if (seen.indexOf(this.value[i]) == -1)
- seen.push(this.value[i])
-
- // set new value
- return this.value = seen
- }
- // Get morphed array at given position
-, at: function(pos) {
- // make sure a destination is defined
- if (!this.destination) return this
-
- // generate morphed array
- for (var i = 0, il = this.value.length, array = []; i < il; i++)
- array.push(this.value[i] + (this.destination[i] - this.value[i]) * pos)
-
- return new SVG.Array(array)
- }
- // Convert array to string
-, toString: function() {
- return this.value.join(' ')
- }
- // Real value
-, valueOf: function() {
- return this.value
- }
- // Parse whitespace separated string
-, parse: function(array) {
- array = array.valueOf()
-
- // if already is an array, no need to parse it
- if (Array.isArray(array)) return array
-
- return array.trim().split(SVG.regex.delimiter).map(parseFloat)
- }
- // Reverse array
-, reverse: function() {
- this.value.reverse()
-
- return this
- }
-, clone: function() {
- var clone = new this.constructor()
- clone.value = array_clone(this.value)
- return clone
- }
+
+// Storage for regular expressions
+SVG.regex = {
+ // Parse unit value
+ numberAndUnit: /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,
+
+ // Parse hex value
+ hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,
+
+ // Parse rgb value
+ rgb: /rgb\((\d+),(\d+),(\d+)\)/,
+
+ // Parse reference id
+ reference: /#([a-z0-9\-_]+)/i,
+
+ // splits a transformation chain
+ transforms: /\)\s*,?\s*/,
+
+ // Whitespace
+ whitespace: /\s/g,
+
+ // Test hex value
+ isHex: /^#[a-f0-9]{3,6}$/i,
+
+ // Test rgb value
+ isRgb: /^rgb\(/,
+
+ // Test css declaration
+ isCss: /[^:]+:[^;]+;?/,
+
+ // Test for blank string
+ isBlank: /^(\s+)?$/,
+
+ // Test for numeric string
+ isNumber: /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
+
+ // Test for percent value
+ isPercent: /^-?[\d.]+%$/,
+
+ // Test for image url
+ isImage: /\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,
+
+ // split at whitespace and comma
+ delimiter: /[\s,]+/,
+
+ // The following regex are used to parse the d attribute of a path
+
+ // Matches all hyphens which are not after an exponent
+ hyphen: /([^e])-/gi,
+
+ // Replaces and tests for all path letters
+ pathLetters: /[MLHVCSQTAZ]/gi,
+
+ // yes we need this one, too
+ isPathLetter: /[MLHVCSQTAZ]/i,
+
+ // matches 0.154.23.45
+ numbersWithDots: /((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi,
+
+ // matches .
+ dots: /\./g
+}
+
+SVG.utils = {
+ // Map function
+ map: function (array, block) {
+ var i
+ var il = array.length
+ var result = []
+
+ for (i = 0; i < il; i++) {
+ result.push(block(array[i]))
+ }
+
+ return result
+ },
+
+ // Filter function
+ filter: function (array, block) {
+ var i
+ var il = array.length
+ var result = []
+
+ for (i = 0; i < il; i++) {
+ if (block(array[i])) { result.push(array[i]) }
+ }
+
+ return result
+ },
+
+ // Degrees to radians
+ radians: function (d) {
+ return d % 360 * Math.PI / 180
+ },
+
+ // Radians to degrees
+ degrees: function (r) {
+ return r * 180 / Math.PI % 360
+ },
+
+ filterSVGElements: function (nodes) {
+ return this.filter(nodes, function (el) { return el instanceof window.SVGElement })
+ }
+
+}
+
+
+SVG.defaults = {
+
+ // Default attribute values
+ attrs: {
+
+ // fill and stroke
+ 'fill-opacity': 1,
+ 'stroke-opacity': 1,
+ 'stroke-width': 0,
+ 'stroke-linejoin': 'miter',
+ 'stroke-linecap': 'butt',
+ fill: '#000000',
+ stroke: '#000000',
+ opacity: 1,
+
+ // position
+ x: 0,
+ y: 0,
+ cx: 0,
+ cy: 0,
+
+ // size
+ width: 0,
+ height: 0,
+
+ // radius
+ r: 0,
+ rx: 0,
+ ry: 0,
+
+ // gradient
+ offset: 0,
+ 'stop-opacity': 1,
+ 'stop-color': '#000000',
+
+ // text
+ 'font-size': 16,
+ 'font-family': 'Helvetica, Arial, sans-serif',
+ 'text-anchor': 'start'
+ }
+}
+
+/* globals fullHex, compToHex */
+
+// Module for color convertions
+SVG.Color = function (color) {
+ var match
+
+ // initialize defaults
+ this.r = 0
+ this.g = 0
+ this.b = 0
+
+ if (!color) return
+
+ // parse color
+ if (typeof color === 'string') {
+ if (SVG.regex.isRgb.test(color)) {
+ // get rgb values
+ match = SVG.regex.rgb.exec(color.replace(SVG.regex.whitespace, ''))
+
+ // parse numeric values
+ this.r = parseInt(match[1])
+ this.g = parseInt(match[2])
+ this.b = parseInt(match[3])
+ } else if (SVG.regex.isHex.test(color)) {
+ // get hex values
+ match = SVG.regex.hex.exec(fullHex(color))
+
+ // parse numeric values
+ this.r = parseInt(match[1], 16)
+ this.g = parseInt(match[2], 16)
+ this.b = parseInt(match[3], 16)
+ }
+ } else if (typeof color === 'object') {
+ this.r = color.r
+ this.g = color.g
+ this.b = color.b
+ }
+}
+
+SVG.extend(SVG.Color, {
+ // Default to hex conversion
+ toString: function () {
+ return this.toHex()
+ },
+ // Build hex value
+ toHex: function () {
+ return '#' +
+ compToHex(this.r) +
+ compToHex(this.g) +
+ compToHex(this.b)
+ },
+ // Build rgb value
+ toRgb: function () {
+ return 'rgb(' + [this.r, this.g, this.b].join() + ')'
+ },
+ // Calculate true brightness
+ brightness: function () {
+ return (this.r / 255 * 0.30) +
+ (this.g / 255 * 0.59) +
+ (this.b / 255 * 0.11)
+ },
+ // Make color morphable
+ morph: function (color) {
+ this.destination = new SVG.Color(color)
+
+ return this
+ },
+ // Get morphed color at given position
+ at: function (pos) {
+ // make sure a destination is defined
+ if (!this.destination) return this
+
+ // normalise pos
+ pos = pos < 0 ? 0 : pos > 1 ? 1 : pos
+
+ // generate morphed color
+ return new SVG.Color({
+ r: ~~(this.r + (this.destination.r - this.r) * pos),
+ g: ~~(this.g + (this.destination.g - this.g) * pos),
+ b: ~~(this.b + (this.destination.b - this.b) * pos)
+ })
+ }
+
+})
+
+// Testers
+
+// Test if given value is a color string
+SVG.Color.test = function (color) {
+ color += ''
+ return SVG.regex.isHex.test(color) ||
+ SVG.regex.isRgb.test(color)
+}
+
+// Test if given value is a rgb object
+SVG.Color.isRgb = function (color) {
+ return color && typeof color.r === 'number' &&
+ typeof color.g === 'number' &&
+ typeof color.b === 'number'
+}
+
+// Test if given value is a color
+SVG.Color.isColor = function (color) {
+ return SVG.Color.isRgb(color) || SVG.Color.test(color)
+}
+
+/* global arrayClone */
+
+// Module for array conversion
+SVG.Array = function (array, fallback) {
+ array = (array || []).valueOf()
+
+ // if array is empty and fallback is provided, use fallback
+ if (array.length === 0 && fallback) {
+ array = fallback.valueOf()
+ }
+
+ // parse array
+ this.value = this.parse(array)
+}
+
+SVG.extend(SVG.Array, {
+ // Make array morphable
+ morph: function (array) {
+ this.destination = this.parse(array)
+
+ // normalize length of arrays
+ if (this.value.length !== this.destination.length) {
+ var lastValue = this.value[this.value.length - 1]
+ var lastDestination = this.destination[this.destination.length - 1]
+
+ while (this.value.length > this.destination.length) {
+ this.destination.push(lastDestination)
+ }
+ while (this.value.length < this.destination.length) {
+ this.value.push(lastValue)
+ }
+ }
+
+ return this
+ },
+ // Clean up any duplicate points
+ settle: function () {
+ // find all unique values
+ for (var i = 0, il = this.value.length, seen = []; i < il; i++) {
+ if (seen.indexOf(this.value[i]) === -1) {
+ seen.push(this.value[i])
+ }
+ }
+
+ // set new value
+ this.value = seen
+ return seen
+ },
+ // Get morphed array at given position
+ at: function (pos) {
+ // make sure a destination is defined
+ if (!this.destination) return this
+
+ // generate morphed array
+ for (var i = 0, il = this.value.length, array = []; i < il; i++) {
+ array.push(this.value[i] + (this.destination[i] - this.value[i]) * pos)
+ }
+
+ return new SVG.Array(array)
+ },
+ // Convert array to string
+ toString: function () {
+ return this.value.join(' ')
+ },
+ // Real value
+ valueOf: function () {
+ return this.value
+ },
+ // Parse whitespace separated string
+ parse: function (array) {
+ array = array.valueOf()
+
+ // if already is an array, no need to parse it
+ if (Array.isArray(array)) return array
+
+ return array.trim().split(SVG.regex.delimiter).map(parseFloat)
+ },
+ // Reverse array
+ reverse: function () {
+ this.value.reverse()
+
+ return this
+ },
+ clone: function () {
+ var clone = new this.constructor()
+ clone.value = arrayClone(this.value)
+ return clone
+ }
})
-// Poly points array
-SVG.PointArray = function(array, fallback) {
- SVG.Array.call(this, array, fallback || [[0,0]])
-}
-
-// Inherit from SVG.Array
-SVG.PointArray.prototype = new SVG.Array
-SVG.PointArray.prototype.constructor = SVG.PointArray
-
-SVG.extend(SVG.PointArray, {
- // Convert array to string
- toString: function() {
- // convert to a poly point string
- for (var i = 0, il = this.value.length, array = []; i < il; i++)
- array.push(this.value[i].join(','))
-
- return array.join(' ')
- }
- // Convert array to line object
-, toLine: function() {
- return {
- x1: this.value[0][0]
- , y1: this.value[0][1]
- , x2: this.value[1][0]
- , y2: this.value[1][1]
- }
- }
- // Get morphed array at given position
-, at: function(pos) {
- // make sure a destination is defined
- if (!this.destination) return this
-
- // generate morphed point string
- for (var i = 0, il = this.value.length, array = []; i < il; i++)
- array.push([
- this.value[i][0] + (this.destination[i][0] - this.value[i][0]) * pos
- , this.value[i][1] + (this.destination[i][1] - this.value[i][1]) * pos
- ])
-
- return new SVG.PointArray(array)
- }
- // Parse point string and flat array
-, parse: function(array) {
- var points = []
-
- array = array.valueOf()
-
- // if it is an array
- if (Array.isArray(array)) {
- // and it is not flat, there is no need to parse it
- if(Array.isArray(array[0])) {
- return array
- }
- } else { // Else, it is considered as a string
- // parse points
- array = array.trim().split(SVG.regex.delimiter).map(parseFloat)
- }
-
- // validate points - https://svgwg.org/svg2-draft/shapes.html#DataTypePoints
- // Odd number of coordinates is an error. In such cases, drop the last odd coordinate.
- if (array.length % 2 !== 0) array.pop()
-
- // wrap points in two-tuples and parse points as floats
- for(var i = 0, len = array.length; i < len; i = i + 2)
- points.push([ array[i], array[i+1] ])
-
- return points
- }
- // Move point string
-, move: function(x, y) {
- var box = this.bbox()
-
- // get relative offset
- x -= box.x
- y -= box.y
-
- // move every point
- if (!isNaN(x) && !isNaN(y))
- for (var i = this.value.length - 1; i >= 0; i--)
- this.value[i] = [this.value[i][0] + x, this.value[i][1] + y]
-
- return this
- }
- // Resize poly string
-, size: function(width, height) {
- var i, box = this.bbox()
-
- // recalculate position of all points according to new size
- for (i = this.value.length - 1; i >= 0; i--) {
- if(box.width) this.value[i][0] = ((this.value[i][0] - box.x) * width) / box.width + box.x
- if(box.height) this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y
- }
-
- return this
- }
- // Get bounding box of points
-, bbox: function() {
- var maxX = -Infinity, maxY = -Infinity, minX = Infinity, minY = Infinity
- this.value.forEach(function(el) {
- maxX = Math.max(el[0], maxX)
- maxY = Math.max(el[1], maxY)
- minX = Math.min(el[0], minX)
- minY = Math.min(el[1], minY)
- })
- return {x: minX, y: minY, width: maxX-minX, height: maxY-minY}
- }
-})
-
-var pathHandlers = {
- M: function(c, p, p0) {
- p.x = p0.x = c[0]
- p.y = p0.y = c[1]
-
- return ['M', p.x, p.y]
- },
- L: function(c, p) {
- p.x = c[0]
- p.y = c[1]
- return ['L', c[0], c[1]]
- },
- H: function(c, p) {
- p.x = c[0]
- return ['H', c[0]]
- },
- V: function(c, p) {
- p.y = c[0]
- return ['V', c[0]]
- },
- C: function(c, p) {
- p.x = c[4]
- p.y = c[5]
- return ['C', c[0], c[1], c[2], c[3], c[4], c[5]]
- },
- S: function(c, p) {
- p.x = c[2]
- p.y = c[3]
- return ['S', c[0], c[1], c[2], c[3]]
- },
- Q: function(c, p) {
- p.x = c[2]
- p.y = c[3]
- return ['Q', c[0], c[1], c[2], c[3]]
- },
- T: function(c, p) {
- p.x = c[0]
- p.y = c[1]
- return ['T', c[0], c[1]]
- },
- Z: function(c, p, p0) {
- p.x = p0.x
- p.y = p0.y
- return ['Z']
- },
- A: function(c, p) {
- p.x = c[5]
- p.y = c[6]
- return ['A', c[0], c[1], c[2], c[3], c[4], c[5], c[6]]
- }
-}
-
-var mlhvqtcsaz = 'mlhvqtcsaz'.split('')
-
-for(var i = 0, il = mlhvqtcsaz.length; i < il; ++i){
- pathHandlers[mlhvqtcsaz[i]] = (function(i){
- return function(c, p, p0) {
- if(i == 'H') c[0] = c[0] + p.x
- else if(i == 'V') c[0] = c[0] + p.y
- else if(i == 'A'){
- c[5] = c[5] + p.x,
- c[6] = c[6] + p.y
- }
- else
- for(var j = 0, jl = c.length; j < jl; ++j) {
- c[j] = c[j] + (j%2 ? p.y : p.x)
- }
-
- return pathHandlers[i](c, p, p0)
- }
- })(mlhvqtcsaz[i].toUpperCase())
-}
-
-// Path points array
-SVG.PathArray = function(array, fallback) {
- SVG.Array.call(this, array, fallback || [['M', 0, 0]])
-}
-
-// Inherit from SVG.Array
-SVG.PathArray.prototype = new SVG.Array
-SVG.PathArray.prototype.constructor = SVG.PathArray
-
-SVG.extend(SVG.PathArray, {
- // Convert array to string
- toString: function() {
- return arrayToString(this.value)
- }
- // Move path string
-, move: function(x, y) {
- // get bounding box of current situation
- var box = this.bbox()
-
- // get relative offset
- x -= box.x
- y -= box.y
-
- if (!isNaN(x) && !isNaN(y)) {
- // move every point
- for (var l, i = this.value.length - 1; i >= 0; i--) {
- l = this.value[i][0]
-
- if (l == 'M' || l == 'L' || l == 'T') {
- this.value[i][1] += x
- this.value[i][2] += y
-
- } else if (l == 'H') {
- this.value[i][1] += x
-
- } else if (l == 'V') {
- this.value[i][1] += y
-
- } else if (l == 'C' || l == 'S' || l == 'Q') {
- this.value[i][1] += x
- this.value[i][2] += y
- this.value[i][3] += x
- this.value[i][4] += y
-
- if (l == 'C') {
- this.value[i][5] += x
- this.value[i][6] += y
- }
-
- } else if (l == 'A') {
- this.value[i][6] += x
- this.value[i][7] += y
- }
-
- }
- }
-
- return this
- }
- // Resize path string
-, size: function(width, height) {
- // get bounding box of current situation
- var i, l, box = this.bbox()
-
- // recalculate position of all points according to new size
- for (i = this.value.length - 1; i >= 0; i--) {
- l = this.value[i][0]
-
- if (l == 'M' || l == 'L' || l == 'T') {
- this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
- this.value[i][2] = ((this.value[i][2] - box.y) * height) / box.height + box.y
-
- } else if (l == 'H') {
- this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
-
- } else if (l == 'V') {
- this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y
-
- } else if (l == 'C' || l == 'S' || l == 'Q') {
- this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
- this.value[i][2] = ((this.value[i][2] - box.y) * height) / box.height + box.y
- this.value[i][3] = ((this.value[i][3] - box.x) * width) / box.width + box.x
- this.value[i][4] = ((this.value[i][4] - box.y) * height) / box.height + box.y
-
- if (l == 'C') {
- this.value[i][5] = ((this.value[i][5] - box.x) * width) / box.width + box.x
- this.value[i][6] = ((this.value[i][6] - box.y) * height) / box.height + box.y
- }
-
- } else if (l == 'A') {
- // resize radii
- this.value[i][1] = (this.value[i][1] * width) / box.width
- this.value[i][2] = (this.value[i][2] * height) / box.height
-
- // move position values
- this.value[i][6] = ((this.value[i][6] - box.x) * width) / box.width + box.x
- this.value[i][7] = ((this.value[i][7] - box.y) * height) / box.height + box.y
- }
-
- }
-
- return this
- }
- // Test if the passed path array use the same path data commands as this path array
-, equalCommands: function(pathArray) {
- var i, il, equalCommands
-
- pathArray = new SVG.PathArray(pathArray)
-
- equalCommands = this.value.length === pathArray.value.length
- for(i = 0, il = this.value.length; equalCommands && i < il; i++) {
- equalCommands = this.value[i][0] === pathArray.value[i][0]
- }
-
- return equalCommands
- }
- // Make path array morphable
-, morph: function(pathArray) {
- pathArray = new SVG.PathArray(pathArray)
-
- if(this.equalCommands(pathArray)) {
- this.destination = pathArray
- } else {
- this.destination = null
- }
-
- return this
- }
- // Get morphed path array at given position
-, at: function(pos) {
- // make sure a destination is defined
- if (!this.destination) return this
-
- var sourceArray = this.value
- , destinationArray = this.destination.value
- , array = [], pathArray = new SVG.PathArray()
- , i, il, j, jl
-
- // Animate has specified in the SVG spec
- // See: https://www.w3.org/TR/SVG11/paths.html#PathElement
- for (i = 0, il = sourceArray.length; i < il; i++) {
- array[i] = [sourceArray[i][0]]
- for(j = 1, jl = sourceArray[i].length; j < jl; j++) {
- array[i][j] = sourceArray[i][j] + (destinationArray[i][j] - sourceArray[i][j]) * pos
- }
- // For the two flags of the elliptical arc command, the SVG spec say:
- // Flags and booleans are interpolated as fractions between zero and one, with any non-zero value considered to be a value of one/true
- // Elliptical arc command as an array followed by corresponding indexes:
- // ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y]
- // 0 1 2 3 4 5 6 7
- if(array[i][0] === 'A') {
- array[i][4] = +(array[i][4] != 0)
- array[i][5] = +(array[i][5] != 0)
- }
- }
-
- // Directly modify the value of a path array, this is done this way for performance
- pathArray.value = array
- return pathArray
- }
- // Absolutize and parse path to array
-, parse: function(array) {
- // if it's already a patharray, no need to parse it
- if (array instanceof SVG.PathArray) return array.valueOf()
-
- // prepare for parsing
- var i, x0, y0, s, seg, arr
- , x = 0
- , y = 0
- , paramCnt = { 'M':2, 'L':2, 'H':1, 'V':1, 'C':6, 'S':4, 'Q':4, 'T':2, 'A':7, 'Z':0 }
-
- if(typeof array == 'string'){
-
- array = array
- .replace(SVG.regex.numbersWithDots, pathRegReplace) // convert 45.123.123 to 45.123 .123
- .replace(SVG.regex.pathLetters, ' $& ') // put some room between letters and numbers
- .replace(SVG.regex.hyphen, '$1 -') // add space before hyphen
- .trim() // trim
- .split(SVG.regex.delimiter) // split into array
-
- }else{
- array = array.reduce(function(prev, curr){
- return [].concat.call(prev, curr)
- }, [])
- }
-
- // array now is an array containing all parts of a path e.g. ['M', '0', '0', 'L', '30', '30' ...]
- var arr = []
- , p = new SVG.Point()
- , p0 = new SVG.Point()
- , index = 0
- , len = array.length
-
- do{
- // Test if we have a path letter
- if(SVG.regex.isPathLetter.test(array[index])){
- s = array[index]
- ++index
- // If last letter was a move command and we got no new, it defaults to [L]ine
- }else if(s == 'M'){
- s = 'L'
- }else if(s == 'm'){
- s = 'l'
- }
-
- arr.push(pathHandlers[s].call(null,
- array.slice(index, (index = index + paramCnt[s.toUpperCase()])).map(parseFloat),
- p, p0
- )
- )
-
- }while(len > index)
-
- return arr
-
- }
- // Get bounding box of path
-, bbox: function() {
- SVG.parser().path.setAttribute('d', this.toString())
- return SVG.parser.nodes.path.getBBox()
- }
-
-})
-
-// Module for unit convertions
-SVG.Number = SVG.invent({
- // Initialize
- create: function(value, unit) {
- // initialize defaults
- this.value = 0
- this.unit = unit || ''
-
- // parse value
- if (typeof value === 'number') {
- // ensure a valid numeric value
- this.value = isNaN(value) ? 0 : !isFinite(value) ? (value < 0 ? -3.4e+38 : +3.4e+38) : value
-
- } else if (typeof value === 'string') {
- unit = value.match(SVG.regex.numberAndUnit)
-
- if (unit) {
- // make value numeric
- this.value = parseFloat(unit[1])
-
- // normalize
- if (unit[5] == '%')
- this.value /= 100
- else if (unit[5] == 's')
- this.value *= 1000
-
- // store unit
- this.unit = unit[5]
- }
-
- } else {
- if (value instanceof SVG.Number) {
- this.value = value.valueOf()
- this.unit = value.unit
- }
- }
-
- }
- // Add methods
-, extend: {
- // Stringalize
- toString: function() {
- return (
- this.unit == '%' ?
- ~~(this.value * 1e8) / 1e6:
- this.unit == 's' ?
- this.value / 1e3 :
- this.value
- ) + this.unit
- }
- , toJSON: function() {
- return this.toString()
- }
- , // Convert to primitive
- valueOf: function() {
- return this.value
- }
- // Add number
- , plus: function(number) {
- number = new SVG.Number(number)
- return new SVG.Number(this + number, this.unit || number.unit)
- }
- // Subtract number
- , minus: function(number) {
- number = new SVG.Number(number)
- return new SVG.Number(this - number, this.unit || number.unit)
- }
- // Multiply number
- , times: function(number) {
- number = new SVG.Number(number)
- return new SVG.Number(this * number, this.unit || number.unit)
- }
- // Divide number
- , divide: function(number) {
- number = new SVG.Number(number)
- return new SVG.Number(this / number, this.unit || number.unit)
- }
- // Convert to different unit
- , to: function(unit) {
- var number = new SVG.Number(this)
-
- if (typeof unit === 'string')
- number.unit = unit
-
- return number
- }
- // Make number morphable
- , morph: function(number) {
- this.destination = new SVG.Number(number)
-
- if(number.relative) {
- this.destination.value += this.value
- }
-
- return this
- }
- // Get morphed number at given position
- , at: function(pos) {
- // Make sure a destination is defined
- if (!this.destination) return this
-
- // Generate new morphed number
- return new SVG.Number(this.destination)
- .minus(this)
- .times(pos)
- .plus(this)
- }
-
- }
-})
-
-SVG.HtmlNode = SVG.invent({
- create: function(element) {
- this.node = element
- }
-
-, extend: {
- add: function(element, i) {
- element = createElement(element)
- if(element instanceof SVG.Nested) {
- element = new SVG.Doc(element.node)
- element.setData(JSON.parse(element.node.getAttribute('svgjs:data')) || {})
- }
-
- if (i == null)
- this.node.appendChild(element.node)
- else if (element.node != this.node.children[i])
- this.node.insertBefore(element.node, this.node.children[i])
-
- return this
- }
-
- , put: function(element, i) {
- this.add(element, i)
- return element
- }
- }
-})
-
-
-SVG.Element = SVG.invent({
- // Initialize node
- create: function(node) {
- // last fired event on node
- this._event = null
-
- // initialize data object
- this.dom = {}
-
- // create circular reference
- if (this.node = node) {
- this.type = node.nodeName
- this.node.instance = this
-
- if(node.hasAttribute('svgjs:data')) {
- // pull svgjs data from the dom (getAttributeNS doesn't work in html5)
- this.setData(JSON.parse(node.getAttribute('svgjs:data')) || {})
- }
- }
- }
-
- // Add class methods
-, extend: {
- // Move over x-axis
- x: function(x) {
- return this.attr('x', x)
- }
- // Move over y-axis
- , y: function(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 = proportionalSize(this, width, height)
-
- return this
- .width(new SVG.Number(p.width))
- .height(new SVG.Number(p.height))
- }
- // Clone element
- , clone: function(parent) {
- // write dom data to the dom so the clone can pickup the data
- this.writeDataToDom()
-
- // clone element and assign new id
- var clone = assignNewId(this.node.cloneNode(true))
-
- // insert the clone in the given parent or after myself
- if(parent) parent.add(clone)
- else this.after(clone)
-
- return clone
- }
- // 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 createElement(parent).put(this)
- }
- // Add element to given container and return container
- , putIn: function(parent) {
- return createElement(parent).add(this)
- }
- // Get / set id
- , id: function(id) {
- // generate new id if no id set
- if(typeof id == 'undefined' && !this.node.id) {
- this.node.id = SVG.eid(this.type)
- }
-
- // dont't set directly width this.node.id to make `null` work correctly
- return this.attr('id', id)
- }
- // 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.css('display', '')
- }
- // Hide element
- , hide: function() {
- return this.css('display', 'none')
- }
- // Is element visible?
- , visible: function() {
- return this.css('display') != 'none'
- }
- // Return id on string conversion
- , toString: function() {
- return this.id()
- }
- // Return array of classes on the node
- , classes: function() {
- var attr = this.attr('class')
-
- return attr == null ? [] : attr.trim().split(SVG.regex.delimiter)
- }
- // Return true if class exists on the node, false otherwise
- , hasClass: function(name) {
- return this.classes().indexOf(name) != -1
- }
- // Add class to the node
- , addClass: function(name) {
- if (!this.hasClass(name)) {
- var array = this.classes()
- array.push(name)
- this.attr('class', array.join(' '))
- }
-
- return this
- }
- // Remove class from the node
- , removeClass: function(name) {
- if (this.hasClass(name)) {
- this.attr('class', this.classes().filter(function(c) {
- return c != name
- }).join(' '))
- }
-
- return this
- }
- // Toggle the presence of a class on the node
- , toggleClass: function(name) {
- return this.hasClass(name) ? this.removeClass(name) : this.addClass(name)
- }
- // Get referenced element form attribute value
- , reference: function(attr) {
- return SVG.get(this.attr(attr))
- }
- // Returns the parent element instance
- , parent: function(type) {
- var parent = this
-
- // check for parent
- if(!parent.node.parentNode) return null
-
- // get parent element
- parent = SVG.adopt(parent.node.parentNode)
-
- if(!type) return parent
-
- // loop trough ancestors if type is given
- while(parent && parent.node instanceof window.SVGElement){
- if(typeof type === 'string' ? parent.matches(type) : parent instanceof type) return parent
- parent = SVG.adopt(parent.node.parentNode)
- }
- }
- // Get parent document
- , doc: function() {
- return this instanceof SVG.Doc ? this : this.parent(SVG.Doc)
- }
- , // Get defs
- defs: function() {
- return this.doc().defs()
- }
- // return array of all ancestors of given type up to the root svg
- , parents: function(type) {
- var parents = [], parent = this
-
- do{
- parent = parent.parent(type)
- if(!parent || !parent.node) break
-
- parents.push(parent)
- } while(parent.parent)
-
- return parents
- }
- // matches the element vs a css selector
- , matches: function(selector){
- return matches(this.node, selector)
- }
- // Returns the svg node to call native svg methods on it
- , native: function() {
- return this.node
- }
- // Import raw svg
- , svg: function(svg) {
- var well, len
-
- // act as a setter if svg is given
- if (svg && this instanceof SVG.Parent) {
-
- // create temporary holder
- well = document.createElementNS(SVG.ns, 'svg')
- // dump raw svg
- well.innerHTML = svg
-
- // transplant nodes
- for (len = well.children.length;len--;) {
- this.node.appendChild(well.firstElementChild)
- }
-
- // otherwise act as a getter
- } else {
- // write svgjs data to the dom
- this.writeDataToDom()
-
- return this.node.outerHTML
- }
-
- return this
- }
- // write svgjs data to the dom
- , writeDataToDom: function() {
-
- // dump variables recursively
- if(this.is(SVG.Parent)){
- this.each(function(){
- this.writeDataToDom()
- })
- }
-
- // remove previously set data
- this.node.removeAttribute('svgjs:data')
-
- if(Object.keys(this.dom).length)
- this.node.setAttribute('svgjs:data', JSON.stringify(this.dom)) // see #428
-
- return this
- }
- // set given data to the elements data property
- , setData: function(o){
- this.dom = o
- return this
- }
- , is: function(obj){
- return is(this, obj)
- }
- }
-})
-
-SVG.easing = {
- '-': function(pos){return pos}
-, '<>':function(pos){return -Math.cos(pos * Math.PI) / 2 + 0.5}
-, '>': function(pos){return Math.sin(pos * Math.PI / 2)}
-, '<': function(pos){return -Math.cos(pos * Math.PI / 2) + 1}
-}
-
-SVG.morph = function(pos){
- return function(from, to) {
- return new SVG.MorphObj(from, to).at(pos)
- }
-}
-
-SVG.Situation = SVG.invent({
-
- create: function(o){
- this.init = false
- this.reversed = false
- this.reversing = false
-
- this.duration = new SVG.Number(o.duration).valueOf()
- this.delay = new SVG.Number(o.delay).valueOf()
-
- this.start = +new Date() + this.delay
- this.finish = this.start + this.duration
- this.ease = o.ease
-
- // this.loop is incremented from 0 to this.loops
- // it is also incremented when in an infinite loop (when this.loops is true)
- this.loop = 0
- this.loops = false
-
- this.animations = {
- // functionToCall: [list of morphable objects]
- // e.g. move: [SVG.Number, SVG.Number]
- }
-
- this.attrs = {
- // holds all attributes which are not represented from a function svg.js provides
- // e.g. someAttr: SVG.Number
- }
-
- this.styles = {
- // holds all styles which should be animated
- // e.g. fill-color: SVG.Color
- }
-
- this.transforms = [
- // holds all transformations as transformation objects
- // e.g. [SVG.Rotate, SVG.Translate, SVG.Matrix]
- ]
-
- this.once = {
- // functions to fire at a specific position
- // e.g. "0.5": function foo(){}
- }
-
- }
-
-})
-
-
-SVG.FX = SVG.invent({
-
- create: function(element) {
- this._target = element
- this.situations = []
- this.active = false
- this.situation = null
- this.paused = false
- this.lastPos = 0
- this.pos = 0
- // The absolute position of an animation is its position in the context of its complete duration (including delay and loops)
- // When performing a delay, absPos is below 0 and when performing a loop, its value is above 1
- this.absPos = 0
- this._speed = 1
- }
-
-, extend: {
-
- /**
- * sets or returns the target of this animation
- * @param o object || number In case of Object it holds all parameters. In case of number its the duration of the animation
- * @param ease function || string Function which should be used for easing or easing keyword
- * @param delay Number indicating the delay before the animation starts
- * @return target || this
- */
- animate: function(o, ease, delay){
-
- if(typeof o == 'object'){
- ease = o.ease
- delay = o.delay
- o = o.duration
- }
-
- var situation = new SVG.Situation({
- duration: o || 1000,
- delay: delay || 0,
- ease: SVG.easing[ease || '-'] || ease
- })
-
- this.queue(situation)
-
- return this
- }
-
- /**
- * sets a delay before the next element of the queue is called
- * @param delay Duration of delay in milliseconds
- * @return this.target()
- */
- , delay: function(delay){
- // The delay is performed by an empty situation with its duration
- // attribute set to the duration of the delay
- var situation = new SVG.Situation({
- duration: delay,
- delay: 0,
- ease: SVG.easing['-']
- })
-
- return this.queue(situation)
- }
-
- /**
- * sets or returns the target of this animation
- * @param null || target SVG.Element which should be set as new target
- * @return target || this
- */
- , target: function(target){
- if(target && target instanceof SVG.Element){
- this._target = target
- return this
- }
-
- return this._target
- }
-
- // returns the absolute position at a given time
- , timeToAbsPos: function(timestamp){
- return (timestamp - this.situation.start) / (this.situation.duration/this._speed)
- }
-
- // returns the timestamp from a given absolute positon
- , absPosToTime: function(absPos){
- return this.situation.duration/this._speed * absPos + this.situation.start
- }
-
- // starts the animationloop
- , startAnimFrame: function(){
- this.stopAnimFrame()
- this.animationFrame = window.requestAnimationFrame(function(){ this.step() }.bind(this))
- }
-
- // cancels the animationframe
- , stopAnimFrame: function(){
- window.cancelAnimationFrame(this.animationFrame)
- }
-
- // kicks off the animation - only does something when the queue is currently not active and at least one situation is set
- , start: function(){
- // dont start if already started
- if(!this.active && this.situation){
- this.active = true
- this.startCurrent()
- }
-
- return this
- }
-
- // start the current situation
- , startCurrent: function(){
- this.situation.start = +new Date + this.situation.delay/this._speed
- this.situation.finish = this.situation.start + this.situation.duration/this._speed
- return this.initAnimations().step()
- }
-
- /**
- * adds a function / Situation to the animation queue
- * @param fn function / situation to add
- * @return this
- */
- , queue: function(fn){
- if(typeof fn == 'function' || fn instanceof SVG.Situation)
- this.situations.push(fn)
-
- if(!this.situation) this.situation = this.situations.shift()
-
- return this
- }
-
- /**
- * pulls next element from the queue and execute it
- * @return this
- */
- , dequeue: function(){
- // stop current animation
- this.stop()
-
- // get next animation from queue
- this.situation = this.situations.shift()
-
- if(this.situation){
- if(this.situation instanceof SVG.Situation) {
- this.start()
- } else {
- // If it is not a SVG.Situation, then it is a function, we execute it
- this.situation.call(this)
- }
- }
-
- return this
- }
-
- // updates all animations to the current state of the element
- // this is important when one property could be changed from another property
- , initAnimations: function() {
- var i, j, source
- var s = this.situation
-
- if(s.init) return this
-
- for(i in s.animations){
- source = this.target()[i]()
-
- if(!Array.isArray(source)) {
- source = [source]
- }
-
- if(!Array.isArray(s.animations[i])) {
- s.animations[i] = [s.animations[i]]
- }
-
- //if(s.animations[i].length > source.length) {
- // source.concat = source.concat(s.animations[i].slice(source.length, s.animations[i].length))
- //}
-
- for(j = source.length; j--;) {
- // The condition is because some methods return a normal number instead
- // of a SVG.Number
- if(s.animations[i][j] instanceof SVG.Number)
- source[j] = new SVG.Number(source[j])
-
- s.animations[i][j] = source[j].morph(s.animations[i][j])
- }
- }
-
- for(i in s.attrs){
- s.attrs[i] = new SVG.MorphObj(this.target().attr(i), s.attrs[i])
- }
-
- for(i in s.styles){
- s.styles[i] = new SVG.MorphObj(this.target().css(i), s.styles[i])
- }
-
- s.initialTransformation = this.target().matrixify()
-
- s.init = true
- return this
- }
- , clearQueue: function(){
- this.situations = []
- return this
- }
- , clearCurrent: function(){
- this.situation = null
- return this
- }
- /** stops the animation immediately
- * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately.
- * @param clearQueue A Boolean indicating whether to remove queued animation as well.
- * @return this
- */
- , stop: function(jumpToEnd, clearQueue){
- var active = this.active
- this.active = false
-
- if(clearQueue){
- this.clearQueue()
- }
-
- if(jumpToEnd && this.situation){
- // initialize the situation if it was not
- !active && this.startCurrent()
- this.atEnd()
- }
-
- this.stopAnimFrame()
-
- return this.clearCurrent()
- }
-
- /** resets the element to the state where the current element has started
- * @return this
- */
- , reset: function(){
- if(this.situation){
- var temp = this.situation
- this.stop()
- this.situation = temp
- this.atStart()
- }
- return this
- }
-
- // Stop the currently-running animation, remove all queued animations, and complete all animations for the element.
- , finish: function(){
-
- this.stop(true, false)
-
- while(this.dequeue().situation && this.stop(true, false));
-
- this.clearQueue().clearCurrent()
-
- return this
- }
-
- // set the internal animation pointer at the start position, before any loops, and updates the visualisation
- , atStart: function() {
- return this.at(0, true)
- }
-
- // set the internal animation pointer at the end position, after all the loops, and updates the visualisation
- , atEnd: function() {
- if (this.situation.loops === true) {
- // If in a infinite loop, we end the current iteration
- this.situation.loops = this.situation.loop + 1
- }
-
- if(typeof this.situation.loops == 'number') {
- // If performing a finite number of loops, we go after all the loops
- return this.at(this.situation.loops, true)
- } else {
- // If no loops, we just go at the end
- return this.at(1, true)
- }
- }
-
- // set the internal animation pointer to the specified position and updates the visualisation
- // if isAbsPos is true, pos is treated as an absolute position
- , at: function(pos, isAbsPos){
- var durDivSpd = this.situation.duration/this._speed
-
- this.absPos = pos
- // If pos is not an absolute position, we convert it into one
- if (!isAbsPos) {
- if (this.situation.reversed) this.absPos = 1 - this.absPos
- this.absPos += this.situation.loop
- }
-
- this.situation.start = +new Date - this.absPos * durDivSpd
- this.situation.finish = this.situation.start + durDivSpd
-
- return this.step(true)
- }
-
- /**
- * sets or returns the speed of the animations
- * @param speed null || Number The new speed of the animations
- * @return Number || this
- */
- , speed: function(speed){
- if (speed === 0) return this.pause()
-
- if (speed) {
- this._speed = speed
- // We use an absolute position here so that speed can affect the delay before the animation
- return this.at(this.absPos, true)
- } else return this._speed
- }
-
- // Make loopable
- , loop: function(times, reverse) {
- var c = this.last()
-
- // store total loops
- c.loops = (times != null) ? times : true
- c.loop = 0
-
- if(reverse) c.reversing = true
- return this
- }
-
- // pauses the animation
- , pause: function(){
- this.paused = true
- this.stopAnimFrame()
-
- return this
- }
-
- // unpause the animation
- , play: function(){
- if(!this.paused) return this
- this.paused = false
- // We use an absolute position here so that the delay before the animation can be paused
- return this.at(this.absPos, true)
- }
-
- /**
- * toggle or set the direction of the animation
- * true sets direction to backwards while false sets it to forwards
- * @param reversed Boolean indicating whether to reverse the animation or not (default: toggle the reverse status)
- * @return this
- */
- , reverse: function(reversed){
- var c = this.last()
-
- if(typeof reversed == 'undefined') c.reversed = !c.reversed
- else c.reversed = reversed
-
- return this
- }
-
-
- /**
- * returns a float from 0-1 indicating the progress of the current animation
- * @param eased Boolean indicating whether the returned position should be eased or not
- * @return number
- */
- , progress: function(easeIt){
- return easeIt ? this.situation.ease(this.pos) : this.pos
- }
-
- /**
- * adds a callback function which is called when the current animation is finished
- * @param fn Function which should be executed as callback
- * @return number
- */
- , after: function(fn){
- var c = this.last()
- , wrapper = function wrapper(e){
- if(e.detail.situation == c){
- fn.call(this, c)
- this.off('finished.fx', wrapper) // prevent memory leak
- }
- }
-
- this.target().on('finished.fx', wrapper)
-
- return this._callStart()
- }
-
- // adds a callback which is called whenever one animation step is performed
- , during: function(fn){
- var c = this.last()
- , wrapper = function(e){
- if(e.detail.situation == c){
- fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, c)
- }
- }
-
- // see above
- this.target().off('during.fx', wrapper).on('during.fx', wrapper)
-
- this.after(function(){
- this.off('during.fx', wrapper)
- })
-
- return this._callStart()
- }
-
- // calls after ALL animations in the queue are finished
- , afterAll: function(fn){
- var wrapper = function wrapper(e){
- fn.call(this)
- this.off('allfinished.fx', wrapper)
- }
-
- // see above
- this.target().off('allfinished.fx', wrapper).on('allfinished.fx', wrapper)
-
- return this._callStart()
- }
-
- // calls on every animation step for all animations
- , duringAll: function(fn){
- var wrapper = function(e){
- fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, e.detail.situation)
- }
-
- this.target().off('during.fx', wrapper).on('during.fx', wrapper)
-
- this.afterAll(function(){
- this.off('during.fx', wrapper)
- })
-
- return this._callStart()
- }
-
- , last: function(){
- return this.situations.length ? this.situations[this.situations.length-1] : this.situation
- }
-
- // adds one property to the animations
- , add: function(method, args, type){
- this.last()[type || 'animations'][method] = args
- return this._callStart()
- }
-
- /** perform one step of the animation
- * @param ignoreTime Boolean indicating whether to ignore time and use position directly or recalculate position based on time
- * @return this
- */
- , step: function(ignoreTime){
-
- // convert current time to an absolute position
- if(!ignoreTime) this.absPos = this.timeToAbsPos(+new Date)
-
- // This part convert an absolute position to a position
- if(this.situation.loops !== false) {
- var absPos, absPosInt, lastLoop
-
- // If the absolute position is below 0, we just treat it as if it was 0
- absPos = Math.max(this.absPos, 0)
- absPosInt = Math.floor(absPos)
-
- if(this.situation.loops === true || absPosInt < this.situation.loops) {
- this.pos = absPos - absPosInt
- lastLoop = this.situation.loop
- this.situation.loop = absPosInt
- } else {
- this.absPos = this.situation.loops
- this.pos = 1
- // The -1 here is because we don't want to toggle reversed when all the loops have been completed
- lastLoop = this.situation.loop - 1
- this.situation.loop = this.situation.loops
- }
-
- if(this.situation.reversing) {
- // Toggle reversed if an odd number of loops as occured since the last call of step
- this.situation.reversed = this.situation.reversed != Boolean((this.situation.loop - lastLoop) % 2)
- }
-
- } else {
- // If there are no loop, the absolute position must not be above 1
- this.absPos = Math.min(this.absPos, 1)
- this.pos = this.absPos
- }
-
- // while the absolute position can be below 0, the position must not be below 0
- if(this.pos < 0) this.pos = 0
-
- if(this.situation.reversed) this.pos = 1 - this.pos
-
-
- // apply easing
- var eased = this.situation.ease(this.pos)
-
- // call once-callbacks
- for(var i in this.situation.once){
- if(i > this.lastPos && i <= eased){
- this.situation.once[i].call(this.target(), this.pos, eased)
- delete this.situation.once[i]
- }
- }
-
- // fire during callback with position, eased position and current situation as parameter
- if(this.active) this.target().fire('during', {pos: this.pos, eased: eased, fx: this, situation: this.situation})
-
- // the user may call stop or finish in the during callback
- // so make sure that we still have a valid situation
- if(!this.situation){
- return this
- }
-
- // apply the actual animation to every property
- this.eachAt()
-
- // do final code when situation is finished
- if((this.pos == 1 && !this.situation.reversed) || (this.situation.reversed && this.pos == 0)){
-
- // stop animation callback
- this.stopAnimFrame()
-
- // fire finished callback with current situation as parameter
- this.target().fire('finished', {fx:this, situation: this.situation})
-
- if(!this.situations.length){
- this.target().fire('allfinished')
-
- // Recheck the length since the user may call animate in the afterAll callback
- if(!this.situations.length){
- this.target().off('.fx') // there shouldnt be any binding left, but to make sure...
- this.active = false
- }
- }
-
- // start next animation
- if(this.active) this.dequeue()
- else this.clearCurrent()
-
- }else if(!this.paused && this.active){
- // we continue animating when we are not at the end
- this.startAnimFrame()
- }
-
- // save last eased position for once callback triggering
- this.lastPos = eased
- return this
-
- }
-
- // calculates the step for every property and calls block with it
- , eachAt: function(){
- var i, len, at, self = this, target = this.target(), s = this.situation
-
- // apply animations which can be called trough a method
- for(i in s.animations){
-
- at = [].concat(s.animations[i]).map(function(el){
- return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
- })
-
- target[i].apply(target, at)
-
- }
-
- // apply animation which has to be applied with attr()
- for(i in s.attrs){
-
- at = [i].concat(s.attrs[i]).map(function(el){
- return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
- })
-
- target.attr.apply(target, at)
-
- }
-
- // apply animation which has to be applied with css()
- for(i in s.styles){
-
- at = [i].concat(s.styles[i]).map(function(el){
- return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
- })
-
- target.css.apply(target, at)
-
- }
-
- // animate initialTransformation which has to be chained
- if(s.transforms.length){
-
- // get initial initialTransformation
- at = s.initialTransformation
- for(i = 0, len = s.transforms.length; i < len; i++){
-
- // get next transformation in chain
- var a = s.transforms[i]
-
- // multiply matrix directly
- if(a instanceof SVG.Matrix){
-
- if(a.relative){
- at = at.multiply(new SVG.Matrix().morph(a).at(s.ease(this.pos)))
- }else{
- at = at.morph(a).at(s.ease(this.pos))
- }
- continue
- }
-
- // when transformation is absolute we have to reset the needed transformation first
- if(!a.relative)
- a.undo(at.extract())
-
- // and reapply it after
- at = at.multiply(a.at(s.ease(this.pos)))
-
- }
-
- // set new matrix on element
- target.matrix(at)
- }
-
- return this
-
- }
-
-
- // adds an once-callback which is called at a specific position and never again
- , once: function(pos, fn, isEased){
- var c = this.last()
- if(!isEased) pos = c.ease(pos)
-
- c.once[pos] = fn
-
- return this
- }
-
- , _callStart: function() {
- setTimeout(function(){this.start()}.bind(this), 0)
- return this
- }
-
- }
-
-, parent: SVG.Element
-
- // Add method to parent elements
-, construct: {
- // Get fx module or create a new one, then animate with given duration and ease
- animate: function(o, ease, delay) {
- return (this.fx || (this.fx = new SVG.FX(this))).animate(o, ease, delay)
- }
- , delay: function(delay){
- return (this.fx || (this.fx = new SVG.FX(this))).delay(delay)
- }
- , stop: function(jumpToEnd, clearQueue) {
- if (this.fx)
- this.fx.stop(jumpToEnd, clearQueue)
-
- return this
- }
- , finish: function() {
- if (this.fx)
- this.fx.finish()
-
- return this
- }
- // Pause current animation
- , pause: function() {
- if (this.fx)
- this.fx.pause()
-
- return this
- }
- // Play paused current animation
- , play: function() {
- if (this.fx)
- this.fx.play()
-
- return this
- }
- // Set/Get the speed of the animations
- , speed: function(speed) {
- if (this.fx)
- if (speed == null)
- return this.fx.speed()
- else
- this.fx.speed(speed)
-
- return this
- }
- }
-
-})
-
-// MorphObj is used whenever no morphable object is given
-SVG.MorphObj = SVG.invent({
-
- create: function(from, to){
- // prepare color for morphing
- if(SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
- // prepare value list for morphing
- if(SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
- // prepare number for morphing
- if(SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
-
- // prepare for plain morphing
- this.value = from
- this.destination = to
- }
-
-, extend: {
- at: function(pos, real){
- return real < 1 ? this.value : this.destination
- },
-
- valueOf: function(){
- return this.value
- }
- }
-
-})
-
-SVG.extend(SVG.FX, {
- // Add animatable attributes
- attr: function(a, v, relative) {
- // apply attributes individually
- if (typeof a == 'object') {
- for (var key in a)
- this.attr(key, a[key])
-
- } else {
- this.add(a, v, 'attrs')
- }
-
- return this
- }
- // Add animatable styles
-, css: function(s, v) {
- if (typeof s == 'object')
- for (var key in s)
- this.css(key, s[key])
-
- else
- this.add(s, v, 'styles')
-
- return this
- }
- // Animatable x-axis
-, x: function(x, relative) {
- if(this.target() instanceof SVG.G){
- this.transform({x:x}, relative)
- return this
- }
-
- var num = new SVG.Number(x)
- num.relative = relative
- return this.add('x', num)
- }
- // Animatable y-axis
-, y: function(y, relative) {
- if(this.target() instanceof SVG.G){
- this.transform({y:y}, relative)
- return this
- }
-
- var num = new SVG.Number(y)
- num.relative = relative
- return this.add('y', num)
- }
- // Animatable center x-axis
-, cx: function(x) {
- return this.add('cx', new SVG.Number(x))
- }
- // Animatable center y-axis
-, cy: function(y) {
- return this.add('cy', new SVG.Number(y))
- }
- // Add animatable move
-, move: function(x, y) {
- return this.x(x).y(y)
- }
- // Add animatable center
-, center: function(x, y) {
- return this.cx(x).cy(y)
- }
- // Add animatable size
-, size: function(width, height) {
- if (this.target() instanceof SVG.Text) {
- // animate font size for Text elements
- this.attr('font-size', width)
-
- } else {
- // animate bbox based size for all other elements
- var box
-
- if(!width || !height){
- box = this.target().bbox()
- }
-
- if(!width){
- width = box.width / box.height * height
- }
-
- if(!height){
- height = box.height / box.width * width
- }
-
- this.add('width' , new SVG.Number(width))
- .add('height', new SVG.Number(height))
-
- }
-
- return this
- }
- // Add animatable width
-, width: function(width) {
- return this.add('width', new SVG.Number(width))
- }
- // Add animatable height
-, height: function(height) {
- return this.add('height', new SVG.Number(height))
- }
- // Add animatable plot
-, plot: function(a, b, c, d) {
- // Lines can be plotted with 4 arguments
- if(arguments.length == 4) {
- return this.plot([a, b, c, d])
- }
-
- return this.add('plot', new (this.target().morphArray)(a))
- }
- // Add leading method
-, leading: function(value) {
- return this.target().leading ?
- this.add('leading', new SVG.Number(value)) :
- this
- }
- // Add animatable viewbox
-, viewbox: function(x, y, width, height) {
- if (this.target() instanceof SVG.Container) {
- this.add('viewbox', new SVG.Box(x, y, width, height))
- }
-
- return this
- }
-, update: function(o) {
- if (this.target() instanceof SVG.Stop) {
- if (typeof o == 'number' || o instanceof SVG.Number) {
- return this.update({
- offset: arguments[0]
- , color: arguments[1]
- , opacity: arguments[2]
- })
- }
-
- 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', o.offset)
- }
-
- return this
- }
-})
-
-SVG.Matrix = SVG.invent({
- // Initialize
- create: function(source) {
- var i, base = arrayToMatrix([1, 0, 0, 1, 0, 0])
-
- // ensure source as object
- source = source instanceof SVG.Element ?
- source.matrixify() :
- typeof source === 'string' ?
- arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat)) :
- arguments.length == 6 ?
- arrayToMatrix([].slice.call(arguments)) :
- Array.isArray(source) ?
- arrayToMatrix(source) :
- typeof source === 'object' ?
- source : base
-
- // merge source
- for (i = abcdef.length - 1; i >= 0; --i)
- this[abcdef[i]] = source[abcdef[i]] != null ?
- source[abcdef[i]] : base[abcdef[i]]
- }
-
- // Add methods
-, extend: {
- // Extract individual transformations
- extract: function() {
- // find delta transform points
- var px = deltaTransformPoint(this, 0, 1)
- , py = deltaTransformPoint(this, 1, 0)
- , skewX = 180 / Math.PI * Math.atan2(px.y, px.x) - 90
-
- return {
- // translation
- x: this.e
- , y: this.f
- , transformedX:(this.e * Math.cos(skewX * Math.PI / 180) + this.f * Math.sin(skewX * Math.PI / 180)) / Math.sqrt(this.a * this.a + this.b * this.b)
- , transformedY:(this.f * Math.cos(skewX * Math.PI / 180) + this.e * Math.sin(-skewX * Math.PI / 180)) / Math.sqrt(this.c * this.c + this.d * this.d)
- // skew
- , skewX: -skewX
- , skewY: 180 / Math.PI * Math.atan2(py.y, py.x)
- // scale
- , scaleX: Math.sqrt(this.a * this.a + this.b * this.b)
- , scaleY: Math.sqrt(this.c * this.c + this.d * this.d)
- // rotation
- , rotation: skewX
- , a: this.a
- , b: this.b
- , c: this.c
- , d: this.d
- , e: this.e
- , f: this.f
- , matrix: new SVG.Matrix(this)
- }
- }
- // Clone matrix
- , clone: function() {
- return new SVG.Matrix(this)
- }
- // Morph one matrix into another
- , morph: function(matrix) {
- // store new destination
- this.destination = new SVG.Matrix(matrix)
-
- return this
- }
- // Get morphed matrix at a given position
- , at: function(pos) {
- // make sure a destination is defined
- if (!this.destination) return this
-
- // calculate morphed matrix at a given position
- var matrix = new SVG.Matrix({
- a: this.a + (this.destination.a - this.a) * pos
- , b: this.b + (this.destination.b - this.b) * pos
- , c: this.c + (this.destination.c - this.c) * pos
- , d: this.d + (this.destination.d - this.d) * pos
- , e: this.e + (this.destination.e - this.e) * pos
- , f: this.f + (this.destination.f - this.f) * pos
- })
-
- return matrix
- }
- // Multiplies by given matrix
- , multiply: function(matrix) {
- return new SVG.Matrix(this.native().multiply(parseMatrix(matrix).native()))
- }
- // Inverses matrix
- , inverse: function() {
- return new SVG.Matrix(this.native().inverse())
- }
- // Translate matrix
- , translate: function(x, y) {
- return new SVG.Matrix(this.native().translate(x || 0, y || 0))
- }
- // Scale matrix
- , scale: function(x, y, cx, cy) {
- // support uniformal scale
- if (arguments.length == 1) {
- y = x
- } else if (arguments.length == 3) {
- cy = cx
- cx = y
- y = x
- }
-
- return this.around(cx, cy, new SVG.Matrix(x, 0, 0, y, 0, 0))
- }
- // Rotate matrix
- , rotate: function(r, cx, cy) {
- // convert degrees to radians
- r = SVG.utils.radians(r)
-
- return this.around(cx, cy, new SVG.Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0))
- }
- // Flip matrix on x or y, at a given offset
- , flip: function(a, o) {
- return a == 'x' ?
- this.scale(-1, 1, o, 0) :
- a == 'y' ?
- this.scale(1, -1, 0, o) :
- this.scale(-1, -1, a, o != null ? o : a)
- }
- // Skew
- , skew: function(x, y, cx, cy) {
- // support uniformal skew
- if (arguments.length == 1) {
- y = x
- } else if (arguments.length == 3) {
- cy = cx
- cx = y
- y = x
- }
-
- // convert degrees to radians
- x = SVG.utils.radians(x)
- y = SVG.utils.radians(y)
-
- return this.around(cx, cy, new SVG.Matrix(1, Math.tan(y), Math.tan(x), 1, 0, 0))
- }
- // SkewX
- , skewX: function(x, cx, cy) {
- return this.skew(x, 0, cx, cy)
- }
- // SkewY
- , skewY: function(y, cx, cy) {
- return this.skew(0, y, cx, cy)
- }
- // Transform around a center point
- , around: function(cx, cy, matrix) {
- return this
- .multiply(new SVG.Matrix(1, 0, 0, 1, cx || 0, cy || 0))
- .multiply(matrix)
- .multiply(new SVG.Matrix(1, 0, 0, 1, -cx || 0, -cy || 0))
- }
- // Convert to native SVGMatrix
- , native: function() {
- // create new matrix
- var matrix = SVG.parser.nodes.svg.node.createSVGMatrix()
-
- // update with current values
- for (var i = abcdef.length - 1; i >= 0; i--)
- matrix[abcdef[i]] = this[abcdef[i]]
-
- return matrix
- }
- // Convert matrix to string
- , toString: function() {
- return 'matrix(' + this.a + ',' + this.b + ',' + this.c + ',' + this.d + ',' + this.e + ',' + this.f + ')'
- }
- }
-
- // Define parent
-, parent: SVG.Element
-
- // Add parent method
-, construct: {
- // Get current matrix
- ctm: function() {
- return new SVG.Matrix(this.node.getCTM())
- },
- // Get current screen matrix
- screenCTM: function() {
- /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537
- This is needed because FF does not return the transformation matrix
- for the inner coordinate system when getScreenCTM() is called on nested svgs.
- However all other Browsers do that */
- if(this instanceof SVG.Nested) {
- var rect = this.rect(1,1)
- var m = rect.node.getScreenCTM()
- rect.remove()
- return new SVG.Matrix(m)
- }
- return new SVG.Matrix(this.node.getScreenCTM())
- }
-
- }
-
-})
-
-SVG.Point = SVG.invent({
- // Initialize
- create: function(x,y) {
- var i, source, base = {x:0, y:0}
-
- // ensure source as object
- source = Array.isArray(x) ?
- {x:x[0], y:x[1]} :
- typeof x === 'object' ?
- {x:x.x, y:x.y} :
- x != null ?
- {x:x, y:(y != null ? y : x)} : base // If y has no value, then x is used has its value
-
- // merge source
- this.x = source.x
- this.y = source.y
- }
-
- // Add methods
-, extend: {
- // Clone point
- clone: function() {
- return new SVG.Point(this)
- }
- // Morph one point into another
- , morph: function(x, y) {
- // store new destination
- this.destination = new SVG.Point(x, y)
-
- return this
- }
- // Get morphed point at a given position
- , at: function(pos) {
- // make sure a destination is defined
- if (!this.destination) return this
-
- // calculate morphed matrix at a given position
- var point = new SVG.Point({
- x: this.x + (this.destination.x - this.x) * pos
- , y: this.y + (this.destination.y - this.y) * pos
- })
-
- return point
- }
- // Convert to native SVGPoint
- , native: function() {
- // create new point
- var point = SVG.parser.nodes.svg.node.createSVGPoint()
-
- // update with current values
- point.x = this.x
- point.y = this.y
-
- return point
- }
- // transform point with matrix
- , transform: function(matrix) {
- return new SVG.Point(this.native().matrixTransform(matrix.native()))
- }
-
- }
-
-})
-
-SVG.extend(SVG.Element, {
-
- // Get point
- point: function(x, y) {
- return new SVG.Point(x,y).transform(this.screenCTM().inverse());
- }
-
-})
-
-SVG.extend(SVG.Element, {
- // Set svg element attribute
- attr: function(a, v, n) {
- // act as full getter
- 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.isNumber.test(v[n].nodeValue) ? 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 if the first and only argument is not an object
- v = this.node.getAttribute(a)
- return v == null ?
- SVG.defaults.attrs[a] :
- SVG.regex.isNumber.test(v) ?
- parseFloat(v) : v
-
- } else {
-
- // convert image fill and stroke to patterns
- if (a == 'fill' || a == 'stroke') {
- if (SVG.regex.isImage.test(v))
- v = this.doc().defs().image(v)
-
- if (v instanceof SVG.Image)
- v = this.doc().defs().pattern(0, 0, function() {
- this.add(v)
- })
- }
-
- // ensure correct numeric values (also accepts NaN and Infinity)
- if (typeof v === 'number')
- v = new SVG.Number(v)
-
- // ensure full hex color
- else if (SVG.Color.isColor(v))
- v = new SVG.Color(v)
-
- // parse array values
- else if (Array.isArray(v))
- v = new SVG.Array(v)
-
- // if the passed attribute is leading...
- if (a == 'leading') {
- // ... call the leading method instead
- if (this.leading)
- this.leading(v)
- } else {
- // set given attribute on node
- typeof n === 'string' ?
- this.node.setAttributeNS(n, a, v.toString()) :
- this.node.setAttribute(a, v.toString())
- }
-
- // rebuild if required
- if (this.rebuild && (a == 'font-size' || a == 'x'))
- this.rebuild(a, v)
- }
-
- return this
- }
+
+
+// Poly points array
+SVG.PointArray = function (array, fallback) {
+ SVG.Array.call(this, array, fallback || [[0, 0]])
+}
+
+// Inherit from SVG.Array
+SVG.PointArray.prototype = new SVG.Array()
+SVG.PointArray.prototype.constructor = SVG.PointArray
+
+SVG.extend(SVG.PointArray, {
+ // Convert array to string
+ toString: function () {
+ // convert to a poly point string
+ for (var i = 0, il = this.value.length, array = []; i < il; i++) {
+ array.push(this.value[i].join(','))
+ }
+
+ return array.join(' ')
+ },
+
+ // Convert array to line object
+ toLine: function () {
+ return {
+ x1: this.value[0][0],
+ y1: this.value[0][1],
+ x2: this.value[1][0],
+ y2: this.value[1][1]
+ }
+ },
+
+ // Get morphed array at given position
+ at: function (pos) {
+ // make sure a destination is defined
+ if (!this.destination) return this
+
+ // generate morphed point string
+ for (var i = 0, il = this.value.length, array = []; i < il; i++) {
+ array.push([
+ this.value[i][0] + (this.destination[i][0] - this.value[i][0]) * pos,
+ this.value[i][1] + (this.destination[i][1] - this.value[i][1]) * pos
+ ])
+ }
+
+ return new SVG.PointArray(array)
+ },
+
+ // Parse point string and flat array
+ parse: function (array) {
+ var points = []
+
+ array = array.valueOf()
+
+ // if it is an array
+ if (Array.isArray(array)) {
+ // and it is not flat, there is no need to parse it
+ if (Array.isArray(array[0])) {
+ return array
+ }
+ } else { // Else, it is considered as a string
+ // parse points
+ array = array.trim().split(SVG.regex.delimiter).map(parseFloat)
+ }
+
+ // validate points - https://svgwg.org/svg2-draft/shapes.html#DataTypePoints
+ // Odd number of coordinates is an error. In such cases, drop the last odd coordinate.
+ if (array.length % 2 !== 0) array.pop()
+
+ // wrap points in two-tuples and parse points as floats
+ for (var i = 0, len = array.length; i < len; i = i + 2) {
+ points.push([ array[i], array[i + 1] ])
+ }
+
+ return points
+ },
+
+ // Move point string
+ move: function (x, y) {
+ var box = this.bbox()
+
+ // get relative offset
+ x -= box.x
+ y -= box.y
+
+ // move every point
+ if (!isNaN(x) && !isNaN(y)) {
+ for (var i = this.value.length - 1; i >= 0; i--) {
+ this.value[i] = [this.value[i][0] + x, this.value[i][1] + y]
+ }
+ }
+
+ return this
+ },
+ // Resize poly string
+ size: function (width, height) {
+ var i
+ var box = this.bbox()
+
+ // recalculate position of all points according to new size
+ for (i = this.value.length - 1; i >= 0; i--) {
+ if (box.width) this.value[i][0] = ((this.value[i][0] - box.x) * width) / box.width + box.x
+ if (box.height) this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y
+ }
+
+ return this
+ },
+
+ // Get bounding box of points
+ bbox: function () {
+ var maxX = -Infinity
+ var maxY = -Infinity
+ var minX = Infinity
+ var minY = Infinity
+ this.value.forEach(function (el) {
+ maxX = Math.max(el[0], maxX)
+ maxY = Math.max(el[1], maxY)
+ minX = Math.min(el[0], minX)
+ minY = Math.min(el[1], minY)
+ })
+ return {x: minX, y: minY, width: maxX - minX, height: maxY - minY}
+ }
+})
+
+/* globals arrayToString, pathRegReplace */
+
+var pathHandlers = {
+ M: function (c, p, p0) {
+ p.x = p0.x = c[0]
+ p.y = p0.y = c[1]
+
+ return ['M', p.x, p.y]
+ },
+ L: function (c, p) {
+ p.x = c[0]
+ p.y = c[1]
+ return ['L', c[0], c[1]]
+ },
+ H: function (c, p) {
+ p.x = c[0]
+ return ['H', c[0]]
+ },
+ V: function (c, p) {
+ p.y = c[0]
+ return ['V', c[0]]
+ },
+ C: function (c, p) {
+ p.x = c[4]
+ p.y = c[5]
+ return ['C', c[0], c[1], c[2], c[3], c[4], c[5]]
+ },
+ S: function (c, p) {
+ p.x = c[2]
+ p.y = c[3]
+ return ['S', c[0], c[1], c[2], c[3]]
+ },
+ Q: function (c, p) {
+ p.x = c[2]
+ p.y = c[3]
+ return ['Q', c[0], c[1], c[2], c[3]]
+ },
+ T: function (c, p) {
+ p.x = c[0]
+ p.y = c[1]
+ return ['T', c[0], c[1]]
+ },
+ Z: function (c, p, p0) {
+ p.x = p0.x
+ p.y = p0.y
+ return ['Z']
+ },
+ A: function (c, p) {
+ p.x = c[5]
+ p.y = c[6]
+ return ['A', c[0], c[1], c[2], c[3], c[4], c[5], c[6]]
+ }
+}
+
+var mlhvqtcsaz = 'mlhvqtcsaz'.split('')
+
+for (var i = 0, il = mlhvqtcsaz.length; i < il; ++i) {
+ pathHandlers[mlhvqtcsaz[i]] = (function (i) {
+ return function (c, p, p0) {
+ if (i === 'H') c[0] = c[0] + p.x
+ else if (i === 'V') c[0] = c[0] + p.y
+ else if (i === 'A') {
+ c[5] = c[5] + p.x
+ c[6] = c[6] + p.y
+ } else {
+ for (var j = 0, jl = c.length; j < jl; ++j) {
+ c[j] = c[j] + (j % 2 ? p.y : p.x)
+ }
+ }
+
+ return pathHandlers[i](c, p, p0)
+ }
+ })(mlhvqtcsaz[i].toUpperCase())
+}
+
+// Path points array
+SVG.PathArray = function (array, fallback) {
+ SVG.Array.call(this, array, fallback || [['M', 0, 0]])
+}
+
+// Inherit from SVG.Array
+SVG.PathArray.prototype = new SVG.Array()
+SVG.PathArray.prototype.constructor = SVG.PathArray
+
+SVG.extend(SVG.PathArray, {
+ // Convert array to string
+ toString: function () {
+ return arrayToString(this.value)
+ },
+ // Move path string
+ move: function (x, y) {
+ // get bounding box of current situation
+ var box = this.bbox()
+
+ // get relative offset
+ x -= box.x
+ y -= box.y
+
+ if (!isNaN(x) && !isNaN(y)) {
+ // move every point
+ for (var l, i = this.value.length - 1; i >= 0; i--) {
+ l = this.value[i][0]
+
+ if (l === 'M' || l === 'L' || l === 'T') {
+ this.value[i][1] += x
+ this.value[i][2] += y
+ } else if (l === 'H') {
+ this.value[i][1] += x
+ } else if (l === 'V') {
+ this.value[i][1] += y
+ } else if (l === 'C' || l === 'S' || l === 'Q') {
+ this.value[i][1] += x
+ this.value[i][2] += y
+ this.value[i][3] += x
+ this.value[i][4] += y
+
+ if (l === 'C') {
+ this.value[i][5] += x
+ this.value[i][6] += y
+ }
+ } else if (l === 'A') {
+ this.value[i][6] += x
+ this.value[i][7] += y
+ }
+ }
+ }
+
+ return this
+ },
+ // Resize path string
+ size: function (width, height) {
+ // get bounding box of current situation
+ var box = this.bbox()
+ var i, l
+
+ // recalculate position of all points according to new size
+ for (i = this.value.length - 1; i >= 0; i--) {
+ l = this.value[i][0]
+
+ if (l === 'M' || l === 'L' || l === 'T') {
+ this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
+ this.value[i][2] = ((this.value[i][2] - box.y) * height) / box.height + box.y
+ } else if (l === 'H') {
+ this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
+ } else if (l === 'V') {
+ this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y
+ } else if (l === 'C' || l === 'S' || l === 'Q') {
+ this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
+ this.value[i][2] = ((this.value[i][2] - box.y) * height) / box.height + box.y
+ this.value[i][3] = ((this.value[i][3] - box.x) * width) / box.width + box.x
+ this.value[i][4] = ((this.value[i][4] - box.y) * height) / box.height + box.y
+
+ if (l === 'C') {
+ this.value[i][5] = ((this.value[i][5] - box.x) * width) / box.width + box.x
+ this.value[i][6] = ((this.value[i][6] - box.y) * height) / box.height + box.y
+ }
+ } else if (l === 'A') {
+ // resize radii
+ this.value[i][1] = (this.value[i][1] * width) / box.width
+ this.value[i][2] = (this.value[i][2] * height) / box.height
+
+ // move position values
+ this.value[i][6] = ((this.value[i][6] - box.x) * width) / box.width + box.x
+ this.value[i][7] = ((this.value[i][7] - box.y) * height) / box.height + box.y
+ }
+ }
+
+ return this
+ },
+ // Test if the passed path array use the same path data commands as this path array
+ equalCommands: function (pathArray) {
+ var i, il, equalCommands
+
+ pathArray = new SVG.PathArray(pathArray)
+
+ equalCommands = this.value.length === pathArray.value.length
+ for (i = 0, il = this.value.length; equalCommands && i < il; i++) {
+ equalCommands = this.value[i][0] === pathArray.value[i][0]
+ }
+
+ return equalCommands
+ },
+ // Make path array morphable
+ morph: function (pathArray) {
+ pathArray = new SVG.PathArray(pathArray)
+
+ if (this.equalCommands(pathArray)) {
+ this.destination = pathArray
+ } else {
+ this.destination = null
+ }
+
+ return this
+ },
+ // Get morphed path array at given position
+ at: function (pos) {
+ // make sure a destination is defined
+ if (!this.destination) return this
+
+ var sourceArray = this.value
+ var destinationArray = this.destination.value
+ var array = []
+ var pathArray = new SVG.PathArray()
+ var i, il, j, jl
+
+ // Animate has specified in the SVG spec
+ // See: https://www.w3.org/TR/SVG11/paths.html#PathElement
+ for (i = 0, il = sourceArray.length; i < il; i++) {
+ array[i] = [sourceArray[i][0]]
+ for (j = 1, jl = sourceArray[i].length; j < jl; j++) {
+ array[i][j] = sourceArray[i][j] + (destinationArray[i][j] - sourceArray[i][j]) * pos
+ }
+ // For the two flags of the elliptical arc command, the SVG spec say:
+ // Flags and booleans are interpolated as fractions between zero and one, with any non-zero value considered to be a value of one/true
+ // Elliptical arc command as an array followed by corresponding indexes:
+ // ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y]
+ // 0 1 2 3 4 5 6 7
+ if (array[i][0] === 'A') {
+ array[i][4] = +(array[i][4] !== 0)
+ array[i][5] = +(array[i][5] !== 0)
+ }
+ }
+
+ // Directly modify the value of a path array, this is done this way for performance
+ pathArray.value = array
+ return pathArray
+ },
+ // Absolutize and parse path to array
+ parse: function (array) {
+ // if it's already a patharray, no need to parse it
+ if (array instanceof SVG.PathArray) return array.valueOf()
+
+ // prepare for parsing
+ var s
+ var paramCnt = { 'M': 2, 'L': 2, 'H': 1, 'V': 1, 'C': 6, 'S': 4, 'Q': 4, 'T': 2, 'A': 7, 'Z': 0 }
+
+ if (typeof array === 'string') {
+ array = array
+ .replace(SVG.regex.numbersWithDots, pathRegReplace) // convert 45.123.123 to 45.123 .123
+ .replace(SVG.regex.pathLetters, ' $& ') // put some room between letters and numbers
+ .replace(SVG.regex.hyphen, '$1 -') // add space before hyphen
+ .trim() // trim
+ .split(SVG.regex.delimiter) // split into array
+ } else {
+ array = array.reduce(function (prev, curr) {
+ return [].concat.call(prev, curr)
+ }, [])
+ }
+
+ // array now is an array containing all parts of a path e.g. ['M', '0', '0', 'L', '30', '30' ...]
+ var result = []
+ var p = new SVG.Point()
+ var p0 = new SVG.Point()
+ var index = 0
+ var len = array.length
+
+ do {
+ // Test if we have a path letter
+ if (SVG.regex.isPathLetter.test(array[index])) {
+ s = array[index]
+ ++index
+ // If last letter was a move command and we got no new, it defaults to [L]ine
+ } else if (s === 'M') {
+ s = 'L'
+ } else if (s === 'm') {
+ s = 'l'
+ }
+
+ result.push(pathHandlers[s].call(null,
+ array.slice(index, (index = index + paramCnt[s.toUpperCase()])).map(parseFloat),
+ p, p0
+ )
+ )
+ } while (len > index)
+
+ return result
+ },
+ // Get bounding box of path
+ bbox: function () {
+ SVG.parser().path.setAttribute('d', this.toString())
+ return SVG.parser.nodes.path.getBBox()
+ }
+
+})
+
+
+// Module for unit convertions
+SVG.Number = SVG.invent({
+ // Initialize
+ create: function (value, unit) {
+ // initialize defaults
+ this.value = 0
+ this.unit = unit || ''
+
+ // parse value
+ if (typeof value === 'number') {
+ // ensure a valid numeric value
+ this.value = isNaN(value) ? 0 : !isFinite(value) ? (value < 0 ? -3.4e+38 : +3.4e+38) : value
+ } else if (typeof value === 'string') {
+ unit = value.match(SVG.regex.numberAndUnit)
+
+ if (unit) {
+ // make value numeric
+ this.value = parseFloat(unit[1])
+
+ // normalize
+ if (unit[5] === '%') { this.value /= 100 } else if (unit[5] === 's') {
+ this.value *= 1000
+ }
+
+ // store unit
+ this.unit = unit[5]
+ }
+ } else {
+ if (value instanceof SVG.Number) {
+ this.value = value.valueOf()
+ this.unit = value.unit
+ }
+ }
+ },
+ // Add methods
+ extend: {
+ // Stringalize
+ toString: function () {
+ return (this.unit === '%' ? ~~(this.value * 1e8) / 1e6
+ : this.unit === 's' ? this.value / 1e3
+ : this.value
+ ) + this.unit
+ },
+ toJSON: function () {
+ return this.toString()
+ }, // Convert to primitive
+ valueOf: function () {
+ return this.value
+ },
+ // Add number
+ plus: function (number) {
+ number = new SVG.Number(number)
+ return new SVG.Number(this + number, this.unit || number.unit)
+ },
+ // Subtract number
+ minus: function (number) {
+ number = new SVG.Number(number)
+ return new SVG.Number(this - number, this.unit || number.unit)
+ },
+ // Multiply number
+ times: function (number) {
+ number = new SVG.Number(number)
+ return new SVG.Number(this * number, this.unit || number.unit)
+ },
+ // Divide number
+ divide: function (number) {
+ number = new SVG.Number(number)
+ return new SVG.Number(this / number, this.unit || number.unit)
+ },
+ // Convert to different unit
+ to: function (unit) {
+ var number = new SVG.Number(this)
+
+ if (typeof unit === 'string') {
+ number.unit = unit
+ }
+
+ return number
+ },
+ // Make number morphable
+ morph: function (number) {
+ this.destination = new SVG.Number(number)
+
+ if (number.relative) {
+ this.destination.value += this.value
+ }
+
+ return this
+ },
+ // Get morphed number at given position
+ at: function (pos) {
+ // Make sure a destination is defined
+ if (!this.destination) return this
+
+ // Generate new morphed number
+ return new SVG.Number(this.destination)
+ .minus(this)
+ .times(pos)
+ .plus(this)
+ }
+
+ }
+})
+
+/* global createElement */
+
+SVG.HtmlNode = SVG.invent({
+ create: function (element) {
+ this.node = element
+ },
+
+ extend: {
+ add: function (element, i) {
+ element = createElement(element)
+ if (element instanceof SVG.Nested) {
+ element = new SVG.Doc(element.node)
+ element.setData(JSON.parse(element.node.getAttribute('svgjs:data')) || {})
+ }
+
+ if (i === null) {
+ this.node.appendChild(element.node)
+ } else if (element.node !== this.node.children[i]) {
+ this.node.insertBefore(element.node, this.node.children[i])
+ }
+
+ return this
+ },
+
+ put: function (element, i) {
+ this.add(element, i)
+ return element
+ }
+ }
+})
+
+/* global proportionalSize, assignNewId, createElement, matches, is */
+
+SVG.Element = SVG.invent({
+ // Initialize node
+ create: function (node) {
+ // last fired event on node
+ this._event = null
+
+ // initialize data object
+ this.dom = {}
+
+ // create circular reference
+ this.node = node
+ if (this.node) {
+ this.type = node.nodeName
+ this.node.instance = this
+
+ if (node.hasAttribute('svgjs:data')) {
+ // pull svgjs data from the dom (getAttributeNS doesn't work in html5)
+ this.setData(JSON.parse(node.getAttribute('svgjs:data')) || {})
+ }
+ }
+ },
+
+ // Add class methods
+ extend: {
+ // Move over x-axis
+ x: function (x) {
+ return this.attr('x', x)
+ },
+
+ // Move over y-axis
+ y: function (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 = proportionalSize(this, width, height)
+
+ return this
+ .width(new SVG.Number(p.width))
+ .height(new SVG.Number(p.height))
+ },
+
+ // Clone element
+ clone: function (parent) {
+ // write dom data to the dom so the clone can pickup the data
+ this.writeDataToDom()
+
+ // clone element and assign new id
+ var clone = assignNewId(this.node.cloneNode(true))
+
+ // insert the clone in the given parent or after myself
+ if (parent) parent.add(clone)
+ else this.after(clone)
+
+ return clone
+ },
+
+ // 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 createElement(parent).put(this)
+ },
+
+ // Add element to given container and return container
+ putIn: function (parent) {
+ return createElement(parent).add(this)
+ },
+
+ // Get / set id
+ id: function (id) {
+ // generate new id if no id set
+ if (typeof id === 'undefined' && !this.node.id) {
+ this.node.id = SVG.eid(this.type)
+ }
+
+ // dont't set directly width this.node.id to make `null` work correctly
+ return this.attr('id', id)
+ },
+
+ // 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.css('display', '')
+ },
+
+ // Hide element
+ hide: function () {
+ return this.css('display', 'none')
+ },
+
+ // Is element visible?
+ visible: function () {
+ return this.css('display') !== 'none'
+ },
+
+ // Return id on string conversion
+ toString: function () {
+ return this.id()
+ },
+
+ // Return array of classes on the node
+ classes: function () {
+ var attr = this.attr('class')
+ return attr == null ? [] : attr.trim().split(SVG.regex.delimiter)
+ },
+
+ // Return true if class exists on the node, false otherwise
+ hasClass: function (name) {
+ return this.classes().indexOf(name) !== -1
+ },
+
+ // Add class to the node
+ addClass: function (name) {
+ if (!this.hasClass(name)) {
+ var array = this.classes()
+ array.push(name)
+ this.attr('class', array.join(' '))
+ }
+
+ return this
+ },
+
+ // Remove class from the node
+ removeClass: function (name) {
+ if (this.hasClass(name)) {
+ this.attr('class', this.classes().filter(function (c) {
+ return c !== name
+ }).join(' '))
+ }
+
+ return this
+ },
+
+ // Toggle the presence of a class on the node
+ toggleClass: function (name) {
+ return this.hasClass(name) ? this.removeClass(name) : this.addClass(name)
+ },
+
+ // Get referenced element form attribute value
+ reference: function (attr) {
+ return SVG.get(this.attr(attr))
+ },
+
+ // Returns the parent element instance
+ parent: function (type) {
+ var parent = this
+
+ // check for parent
+ if (!parent.node.parentNode) return null
+
+ // get parent element
+ parent = SVG.adopt(parent.node.parentNode)
+
+ if (!type) return parent
+
+ // loop trough ancestors if type is given
+ while (parent && parent.node instanceof window.SVGElement) {
+ if (typeof type === 'string' ? parent.matches(type) : parent instanceof type) return parent
+ parent = SVG.adopt(parent.node.parentNode)
+ }
+ },
+
+ // Get parent document
+ doc: function () {
+ return this instanceof SVG.Doc ? this : this.parent(SVG.Doc)
+ },
+
+ // Get defs
+ defs: function () {
+ return this.doc().defs()
+ },
+
+ // return array of all ancestors of given type up to the root svg
+ parents: function (type) {
+ var parents = []
+ var parent = this
+
+ do {
+ parent = parent.parent(type)
+ if (!parent || !parent.node) break
+
+ parents.push(parent)
+ } while (parent.parent)
+
+ return parents
+ },
+
+ // matches the element vs a css selector
+ matches: function (selector) {
+ return matches(this.node, selector)
+ },
+
+ // Returns the svg node to call native svg methods on it
+ native: function () {
+ return this.node
+ },
+
+ // Import raw svg
+ svg: function (svg) {
+ var well, len
+
+ // act as a setter if svg is given
+ if (svg && this instanceof SVG.Parent) {
+ // create temporary holder
+ well = document.createElementNS(SVG.ns, 'svg')
+ // dump raw svg
+ well.innerHTML = svg
+
+ // transplant nodes
+ for (len = well.children.length; len--;) {
+ this.node.appendChild(well.firstElementChild)
+ }
+
+ // otherwise act as a getter
+ } else {
+ // write svgjs data to the dom
+ this.writeDataToDom()
+
+ return this.node.outerHTML
+ }
+
+ return this
+ },
+
+ // write svgjs data to the dom
+ writeDataToDom: function () {
+ // dump variables recursively
+ if (this.is(SVG.Parent)) {
+ this.each(function () {
+ this.writeDataToDom()
+ })
+ }
+
+ // remove previously set data
+ this.node.removeAttribute('svgjs:data')
+
+ if (Object.keys(this.dom).length) {
+ this.node.setAttribute('svgjs:data', JSON.stringify(this.dom)) // see #428
+ }
+ return this
+ },
+
+ // set given data to the elements data property
+ setData: function (o) {
+ this.dom = o
+ return this
+ },
+ is: function (obj) {
+ return is(this, obj)
+ }
+ }
})
-SVG.extend(SVG.Element, {
- // Add transformations
- transform: function(o, relative) {
- // get target in case of the fx module, otherwise reference this
- var target = this
- , matrix, bbox
-
- // act as a getter
- if (typeof o !== 'object') {
- // get current matrix
- matrix = new SVG.Matrix(target).extract()
-
- return typeof o === 'string' ? matrix[o] : matrix
- }
-
- // get current matrix
- matrix = new SVG.Matrix(target)
-
- // ensure relative flag
- relative = !!relative || !!o.relative
-
- // act on matrix
- if (o.a != null) {
- matrix = relative ?
- // relative
- matrix.multiply(new SVG.Matrix(o)) :
- // absolute
- new SVG.Matrix(o)
-
- // act on rotation
- } else if (o.rotation != null) {
- // ensure centre point
- ensureCentre(o, target)
-
- // apply transformation
- matrix = relative ?
- // relative
- matrix.rotate(o.rotation, o.cx, o.cy) :
- // absolute
- matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy)
-
- // act on scale
- } else if (o.scale != null || o.scaleX != null || o.scaleY != null) {
- // ensure centre point
- ensureCentre(o, target)
-
- // ensure scale values on both axes
- o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
- o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
-
- if (!relative) {
- // absolute; multiply inversed values
- var e = matrix.extract()
- o.scaleX = o.scaleX * 1 / e.scaleX
- o.scaleY = o.scaleY * 1 / e.scaleY
- }
-
- matrix = matrix.scale(o.scaleX, o.scaleY, o.cx, o.cy)
-
- // act on skew
- } else if (o.skew != null || o.skewX != null || o.skewY != null) {
- // ensure centre point
- ensureCentre(o, target)
-
- // ensure skew values on both axes
- o.skewX = o.skew != null ? o.skew : o.skewX != null ? o.skewX : 0
- o.skewY = o.skew != null ? o.skew : o.skewY != null ? o.skewY : 0
-
- if (!relative) {
- // absolute; reset skew values
- var e = matrix.extract()
- matrix = matrix.multiply(new SVG.Matrix().skew(e.skewX, e.skewY, o.cx, o.cy).inverse())
- }
-
- matrix = matrix.skew(o.skewX, o.skewY, o.cx, o.cy)
-
- // act on flip
- } else if (o.flip) {
- if(o.flip == 'x' || o.flip == 'y') {
- o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset
- } else {
- if(o.offset == null) {
- bbox = target.bbox()
- o.flip = bbox.cx
- o.offset = bbox.cy
- } else {
- o.flip = o.offset
- }
- }
-
- matrix = new SVG.Matrix().flip(o.flip, o.offset)
-
- // act on translate
- } else if (o.x != null || o.y != null) {
- if (relative) {
- // relative
- matrix = matrix.translate(o.x, o.y)
- } else {
- // absolute
- if (o.x != null) matrix.e = o.x
- if (o.y != null) matrix.f = o.y
- }
- }
-
- return this.attr('transform', matrix)
- }
-})
-
-SVG.extend(SVG.FX, {
- transform: function(o, relative) {
- // get target in case of the fx module, otherwise reference this
- var target = this.target()
- , matrix, bbox
-
- // act as a getter
- if (typeof o !== 'object') {
- // get current matrix
- matrix = new SVG.Matrix(target).extract()
-
- return typeof o === 'string' ? matrix[o] : matrix
- }
-
- // ensure relative flag
- relative = !!relative || !!o.relative
-
- // act on matrix
- if (o.a != null) {
- matrix = new SVG.Matrix(o)
-
- // act on rotation
- } else if (o.rotation != null) {
- // ensure centre point
- ensureCentre(o, target)
-
- // apply transformation
- matrix = new SVG.Rotate(o.rotation, o.cx, o.cy)
-
- // act on scale
- } else if (o.scale != null || o.scaleX != null || o.scaleY != null) {
- // ensure centre point
- ensureCentre(o, target)
-
- // ensure scale values on both axes
- o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
- o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
-
- matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy)
-
- // act on skew
- } else if (o.skewX != null || o.skewY != null) {
- // ensure centre point
- ensureCentre(o, target)
-
- // ensure skew values on both axes
- o.skewX = o.skewX != null ? o.skewX : 0
- o.skewY = o.skewY != null ? o.skewY : 0
-
- matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy)
-
- // act on flip
- } else if (o.flip) {
- if(o.flip == 'x' || o.flip == 'y') {
- o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset
- } else {
- if(o.offset == null) {
- bbox = target.bbox()
- o.flip = bbox.cx
- o.offset = bbox.cy
- } else {
- o.flip = o.offset
- }
- }
-
- matrix = new SVG.Matrix().flip(o.flip, o.offset)
-
- // act on translate
- } else if (o.x != null || o.y != null) {
- matrix = new SVG.Translate(o.x, o.y)
- }
-
- if(!matrix) return this
-
- matrix.relative = relative
-
- this.last().transforms.push(matrix)
-
- return this._callStart()
- }
-})
-
-SVG.extend(SVG.Element, {
- // Reset all transformations
- untransform: function() {
- return this.attr('transform', null)
- },
- // merge the whole transformation chain into one matrix and returns it
- matrixify: function() {
-
- var matrix = (this.attr('transform') || '')
- // split transformations
- .split(SVG.regex.transforms).slice(0,-1).map(function(str){
- // generate key => value pairs
- var kv = str.trim().split('(')
- return [kv[0], kv[1].split(SVG.regex.delimiter).map(function(str){ return parseFloat(str) })]
- })
- // merge every transformation into one matrix
- .reduce(function(matrix, transform){
-
- if(transform[0] == 'matrix') return matrix.multiply(arrayToMatrix(transform[1]))
- return matrix[transform[0]].apply(matrix, transform[1])
-
- }, new SVG.Matrix())
-
- return matrix
- },
- // add an element to another parent without changing the visual representation on the screen
- toParent: function(parent) {
- if(this == parent) return this
- var ctm = this.screenCTM()
- var pCtm = parent.screenCTM().inverse()
-
- this.addTo(parent).untransform().transform(pCtm.multiply(ctm))
-
- return this
- },
- // same as above with parent equals root-svg
- toDoc: function() {
- return this.toParent(this.doc())
- }
-
-})
-
-SVG.Transformation = SVG.invent({
-
- create: function(source, inversed){
-
- if(arguments.length > 1 && typeof inversed != 'boolean'){
- return this.constructor.call(this, [].slice.call(arguments))
- }
-
- if(Array.isArray(source)){
- for(var i = 0, len = this.arguments.length; i < len; ++i){
- this[this.arguments[i]] = source[i]
- }
- } else if(typeof source == 'object'){
- for(var i = 0, len = this.arguments.length; i < len; ++i){
- this[this.arguments[i]] = source[this.arguments[i]]
- }
- }
-
- this.inversed = false
-
- if(inversed === true){
- this.inversed = true
- }
-
- }
-
-, extend: {
-
- arguments: []
- , method: ''
-
- , at: function(pos){
-
- var params = []
-
- for(var i = 0, len = this.arguments.length; i < len; ++i){
- params.push(this[this.arguments[i]])
- }
-
- var m = this._undo || new SVG.Matrix()
-
- m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos)
-
- return this.inversed ? m.inverse() : m
-
- }
-
- , undo: function(o){
- for(var i = 0, len = this.arguments.length; i < len; ++i){
- o[this.arguments[i]] = typeof this[this.arguments[i]] == 'undefined' ? 0 : o[this.arguments[i]]
- }
-
- // The method SVG.Matrix.extract which was used before calling this
- // method to obtain a value for the parameter o doesn't return a cx and
- // a cy so we use the ones that were provided to this object at its creation
- o.cx = this.cx
- o.cy = this.cy
-
- this._undo = new SVG[capitalize(this.method)](o, true).at(1)
-
- return this
- }
-
- }
-
-})
-
-SVG.Translate = SVG.invent({
-
- parent: SVG.Matrix
-, inherit: SVG.Transformation
-
-, create: function(source, inversed){
- this.constructor.apply(this, [].slice.call(arguments))
- }
-
-, extend: {
- arguments: ['transformedX', 'transformedY']
- , method: 'translate'
- }
-
-})
-
-SVG.Rotate = SVG.invent({
-
- parent: SVG.Matrix
-, inherit: SVG.Transformation
-
-, create: function(source, inversed){
- this.constructor.apply(this, [].slice.call(arguments))
- }
-
-, extend: {
- arguments: ['rotation', 'cx', 'cy']
- , method: 'rotate'
- , at: function(pos){
- var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy)
- return this.inversed ? m.inverse() : m
- }
- , undo: function(o){
- this._undo = o
- return this
- }
- }
-
-})
-
-SVG.Scale = SVG.invent({
-
- parent: SVG.Matrix
-, inherit: SVG.Transformation
-
-, create: function(source, inversed){
- this.constructor.apply(this, [].slice.call(arguments))
- }
-
-, extend: {
- arguments: ['scaleX', 'scaleY', 'cx', 'cy']
- , method: 'scale'
- }
-
-})
-
-SVG.Skew = SVG.invent({
-
- parent: SVG.Matrix
-, inherit: SVG.Transformation
-
-, create: function(source, inversed){
- this.constructor.apply(this, [].slice.call(arguments))
- }
-
-, extend: {
- arguments: ['skewX', 'skewY', 'cx', 'cy']
- , method: 'skew'
- }
-
-})
-
-SVG.extend(SVG.Element, {
- // Dynamic style generator
- css: function(s, v) {
- var t, i, ret = {}
- if (arguments.length == 0) {
- // get full style as object
- this.node.style.cssText.split(/\s*;\s*/).filter(function(el) { return !!el.length }).forEach(function(el) {
- t = el.split(/\s*:\s*/)
- ret[t[0]] = t[1]
- })
- return ret
- }
-
- if (arguments.length < 2) {
- // get style properties in the array
- if(Array.isArray(s)) {
- for(i = s.length; i--;) {
- ret[camelCase(s[i])] = this.node.style[camelCase(s[i])]
- }
- return ret
- }
-
- // get style for property
- if(typeof s == 'string') {
- return this.node.style[camelCase(s)]
- }
-
- // set styles in object
- if(typeof s == 'object') {
- for(i in s) {
- // set empty string if null/undefined/'' was given
- this.node.style[camelCase(i)] = (s[i] == null || SVG.regex.isBlank.test(s[i])) ? '' : s[i]
- }
- }
- }
-
- // set style for property
- if (arguments.length == 2) {
- this.node.style[camelCase(s)] = (v == null || SVG.regex.isBlank.test(v)) ? '' : v
- }
-
- return this
- }
-})
-
-SVG.Parent = SVG.invent({
- // Initialize node
- create: function(node) {
- this.constructor.call(this, node)
- }
-
- // Inherit from
-, inherit: SVG.Element
-
- // Add class methods
-, extend: {
- // Returns all child elements
- children: function() {
- return SVG.utils.map(this.node.children, function(node) {
- return SVG.adopt(node)
- })
- }
- // Add given element at a position
- , add: function(element, i) {
- element = createElement(element)
-
- if (i == null)
- this.node.appendChild(element.node)
- else if (element.node != this.node.children[i])
- this.node.insertBefore(element.node, this.node.children[i])
-
- return this
- }
- // Basically does the same as `add()` but returns the added element instead
- , put: function(element, i) {
- this.add(element, i)
- return element.instance || 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 [].slice.call(this.node.children).indexOf(element.node)
- }
- // Get a element at the given index
- , get: function(i) {
- return SVG.adopt(this.node.children[i])
- }
- // Get first child
- , first: function() {
- return this.get(0)
- }
- // Get the last child
- , last: function() {
- return this.get(this.node.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.Parent))
- children[i].each(block, deep)
- }
-
- return this
- }
- // Remove a given child
- , removeElement: function(element) {
- this.node.removeChild(element.node)
-
- return this
- }
- // Remove all elements in this container
- , clear: function() {
- // remove children
- while(this.node.hasChildNodes())
- this.node.removeChild(this.node.lastChild)
-
- // remove defs reference
- delete this._defs
-
- return this
- }
- }
-
-})
-
-SVG.extend(SVG.Parent, {
- flatten: function(parent) {
- if(this instanceof SVG.Defs) return this
-
- parent = parent || (this instanceof SVG.Doc ? this : this.parent(SVG.Parent))
-
- this.each(function(){
- if(this instanceof SVG.Defs) return this
- if(this instanceof SVG.Parent) return this.flatten(parent)
- return this.toParent(parent)
- })
-
- // we need this so that SVG.Doc does not get removed
- this.node.firstElementChild || this.remove()
-
- return this
- }
-})
-
-SVG.Container = SVG.invent({
- // Initialize node
- create: function(node) {
- this.constructor.call(this, node)
- }
-
- // Inherit from
-, inherit: SVG.Parent
-
+
+SVG.easing = {
+ '-': function (pos) { return pos },
+ '<>': function (pos) { return -Math.cos(pos * Math.PI) / 2 + 0.5 },
+ '>': function (pos) { return Math.sin(pos * Math.PI / 2) },
+ '<': function (pos) { return -Math.cos(pos * Math.PI / 2) + 1 }
+}
+
+SVG.morph = function (pos) {
+ return function (from, to) {
+ return new SVG.MorphObj(from, to).at(pos)
+ }
+}
+
+SVG.Situation = SVG.invent({
+
+ create: function (o) {
+ this.init = false
+ this.reversed = false
+ this.reversing = false
+
+ this.duration = new SVG.Number(o.duration).valueOf()
+ this.delay = new SVG.Number(o.delay).valueOf()
+
+ this.start = +new Date() + this.delay
+ this.finish = this.start + this.duration
+ this.ease = o.ease
+
+ // this.loop is incremented from 0 to this.loops
+ // it is also incremented when in an infinite loop (when this.loops is true)
+ this.loop = 0
+ this.loops = false
+
+ this.animations = {
+ // functionToCall: [list of morphable objects]
+ // e.g. move: [SVG.Number, SVG.Number]
+ }
+
+ this.attrs = {
+ // holds all attributes which are not represented from a function svg.js provides
+ // e.g. someAttr: SVG.Number
+ }
+
+ this.styles = {
+ // holds all styles which should be animated
+ // e.g. fill-color: SVG.Color
+ }
+
+ this.transforms = [
+ // holds all transformations as transformation objects
+ // e.g. [SVG.Rotate, SVG.Translate, SVG.Matrix]
+ ]
+
+ this.once = {
+ // functions to fire at a specific position
+ // e.g. "0.5": function foo(){}
+ }
+ }
+
})
-// Add events to elements
-;[ 'click'
- , 'dblclick'
- , 'mousedown'
- , 'mouseup'
- , 'mouseover'
- , 'mouseout'
- , 'mousemove'
- // , 'mouseenter' -> not supported by IE
- // , 'mouseleave' -> not supported by IE
- , 'touchstart'
- , 'touchmove'
- , 'touchleave'
- , 'touchend'
- , 'touchcancel' ].forEach(function(event) {
-
- // add event to SVG.Element
- SVG.Element.prototype[event] = function(f) {
- // bind event to element rather than element node
- SVG.on(this, event, f)
- return this
- }
-})
-
-// Initialize listeners stack
-SVG.listeners = []
-SVG.handlerMap = []
-SVG.listenerId = 0
-
-// Add event binder in the SVG namespace
-SVG.on = function(node, events, listener, binding, options) {
- events.split(SVG.regex.delimiter).forEach(function(event) {
- // create listener, get object-index
- var l = listener.bind(binding || node)
- , n = node instanceof SVG.Element ? node.node : node
- , index = (SVG.handlerMap.indexOf(n) + 1 || SVG.handlerMap.push(n)) - 1
- , ev = event.split('.')[0]
- , ns = event.split('.')[1] || '*'
-
- // ensure valid object
- SVG.listeners[index] = SVG.listeners[index] || {}
- SVG.listeners[index][ev] = SVG.listeners[index][ev] || {}
- SVG.listeners[index][ev][ns] = SVG.listeners[index][ev][ns] || {}
-
- if(!listener._svgjsListenerId)
- listener._svgjsListenerId = ++SVG.listenerId
-
- // reference listener
- SVG.listeners[index][ev][ns][listener._svgjsListenerId] = l
-
- // add listener
- n.addEventListener(ev, l, options || false)
- })
-}
-
-// Add event unbinder in the SVG namespace
-SVG.off = function(node, event, listener) {
- var index = SVG.handlerMap.indexOf(node)
- , ev = event && event.split('.')[0]
- , ns = event && event.split('.')[1]
- , namespace = ''
-
- if(index == -1) return
-
- if (listener) {
- if(typeof listener == 'function') listener = listener._svgjsListenerId
- if(!listener) return
-
- // remove listener reference
- if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns || '*']) {
- // remove listener
- node.removeEventListener(ev, SVG.listeners[index][ev][ns || '*'][listener], false)
-
- delete SVG.listeners[index][ev][ns || '*'][listener]
- }
-
- } else if (ns && ev) {
- // remove all listeners for a namespaced event
- if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns]) {
- for (listener in SVG.listeners[index][ev][ns])
- SVG.off(node, [ev, ns].join('.'), listener)
-
- delete SVG.listeners[index][ev][ns]
- }
-
- } else if (ns){
- // remove all listeners for a specific namespace
- for(event in SVG.listeners[index]){
- for(namespace in SVG.listeners[index][event]){
- if(ns === namespace){
- SVG.off(node, [event, ns].join('.'))
- }
- }
- }
-
- } else if (ev) {
- // remove all listeners for the event
- if (SVG.listeners[index][ev]) {
- for (namespace in SVG.listeners[index][ev])
- SVG.off(node, [ev, namespace].join('.'))
-
- delete SVG.listeners[index][ev]
- }
-
- } else {
- // remove all listeners on a given node
- for (event in SVG.listeners[index])
- SVG.off(node, event)
-
- delete SVG.listeners[index]
- delete SVG.handlerMap[index]
-
- }
-}
-
-//
-SVG.extend(SVG.Element, {
- // Bind given event to listener
- on: function(event, listener, binding, options) {
- SVG.on(this, event, listener, binding, options)
-
- return this
- }
- // Unbind event from listener
-, off: function(event, listener) {
- SVG.off(this.node, event, listener)
-
- return this
- }
- // Fire given event
-, fire: function(event, data) {
-
- // Dispatch event
- if(event instanceof window.Event){
- this.node.dispatchEvent(event)
- }else{
- this.node.dispatchEvent(event = new window.CustomEvent(event, {detail:data, cancelable: true}))
- }
-
- this._event = event
- return this
- }
-, event: function() {
- return this._event
- }
-})
-
-SVG.Defs = SVG.invent({
- // Initialize node
- create: 'defs'
-
- // Inherit from
-, inherit: SVG.Container
-})
-
-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.transform('x') : this.transform({ x: x - this.x() }, true)
- }
- // Move over y-axis
- , y: function(y) {
- return y == null ? this.transform('y') : this.transform({ y: y - this.y() }, true)
- }
- // Move by center over x-axis
- , cx: function(x) {
- return x == null ? this.gbox().cx : this.x(x - this.gbox().width / 2)
- }
- // Move by center over y-axis
- , cy: function(y) {
- return y == null ? this.gbox().cy : this.y(y - this.gbox().height / 2)
- }
- , gbox: function() {
-
- var bbox = this.bbox()
- , trans = this.transform()
-
- bbox.x += trans.x
- bbox.x2 += trans.x
- bbox.cx += trans.x
-
- bbox.y += trans.y
- bbox.y2 += trans.y
- bbox.cy += trans.y
-
- return bbox
- }
- }
-
- // Add parent method
-, construct: {
- // Create a group element
- group: function() {
- return this.put(new SVG.G)
- }
- }
-})
-
-// ### This module adds backward / forward functionality to elements.
-
-//
-SVG.extend(SVG.Element, {
- // Get all siblings, including myself
- siblings: function() {
- return this.parent().children()
- }
- // Get the curent position siblings
-, position: function() {
- return this.parent().index(this)
- }
- // Get the next element (will return null if there is none)
-, next: function() {
- return this.siblings()[this.position() + 1]
- }
- // Get the next element (will return null if there is none)
-, prev: function() {
- return this.siblings()[this.position() - 1]
- }
- // Send given element one step forward
-, forward: function() {
- var i = this.position() + 1
- , p = this.parent()
-
- // move node one step forward
- p.removeElement(this).add(this, i)
-
- // make sure defs node is always at the top
- if (p instanceof SVG.Doc)
- p.node.appendChild(p.defs().node)
-
- return this
- }
- // Send given element one step backward
-, backward: function() {
- var i = this.position()
-
- if (i > 0)
- this.parent().removeElement(this).add(this, i - 1)
-
- return this
- }
- // Send given element all the way to the front
-, front: function() {
- var p = this.parent()
-
- // Move node forward
- p.node.appendChild(this.node)
-
- // Make sure defs node is always at the top
- if (p instanceof SVG.Doc)
- p.node.appendChild(p.defs().node)
-
- return this
- }
- // Send given element all the way to the back
-, back: function() {
- if (this.position() > 0)
- this.parent().removeElement(this).add(this, 0)
-
- return this
- }
- // Inserts a given element before the targeted element
-, before: function(element) {
- element.remove()
-
- var i = this.position()
-
- this.parent().add(element, i)
-
- return this
- }
- // Insters a given element after the targeted element
-, after: function(element) {
- element.remove()
-
- var i = this.position()
-
- this.parent().add(element, i + 1)
-
- return this
- }
-
+
+SVG.FX = SVG.invent({
+
+ create: function (element) {
+ this._target = element
+ this.situations = []
+ this.active = false
+ this.situation = null
+ this.paused = false
+ this.lastPos = 0
+ this.pos = 0
+ // The absolute position of an animation is its position in the context of its complete duration (including delay and loops)
+ // When performing a delay, absPos is below 0 and when performing a loop, its value is above 1
+ this.absPos = 0
+ this._speed = 1
+ },
+
+ extend: {
+
+ /**
+ * sets or returns the target of this animation
+ * @param o object || number In case of Object it holds all parameters. In case of number its the duration of the animation
+ * @param ease function || string Function which should be used for easing or easing keyword
+ * @param delay Number indicating the delay before the animation starts
+ * @return target || this
+ */
+ animate: function (o, ease, delay) {
+ if (typeof o === 'object') {
+ ease = o.ease
+ delay = o.delay
+ o = o.duration
+ }
+
+ var situation = new SVG.Situation({
+ duration: o || 1000,
+ delay: delay || 0,
+ ease: SVG.easing[ease || '-'] || ease
+ })
+
+ this.queue(situation)
+
+ return this
+ },
+
+ /**
+ * sets a delay before the next element of the queue is called
+ * @param delay Duration of delay in milliseconds
+ * @return this.target()
+ */
+ delay: function (delay) {
+ // The delay is performed by an empty situation with its duration
+ // attribute set to the duration of the delay
+ var situation = new SVG.Situation({
+ duration: delay,
+ delay: 0,
+ ease: SVG.easing['-']
+ })
+
+ return this.queue(situation)
+ },
+
+ /**
+ * sets or returns the target of this animation
+ * @param null || target SVG.Element which should be set as new target
+ * @return target || this
+ */
+ target: function (target) {
+ if (target && target instanceof SVG.Element) {
+ this._target = target
+ return this
+ }
+
+ return this._target
+ },
+
+ // returns the absolute position at a given time
+ timeToAbsPos: function (timestamp) {
+ return (timestamp - this.situation.start) / (this.situation.duration / this._speed)
+ },
+
+ // returns the timestamp from a given absolute positon
+ absPosToTime: function (absPos) {
+ return this.situation.duration / this._speed * absPos + this.situation.start
+ },
+
+ // starts the animationloop
+ startAnimFrame: function () {
+ this.stopAnimFrame()
+ this.animationFrame = window.requestAnimationFrame(function () { this.step() }.bind(this))
+ },
+
+ // cancels the animationframe
+ stopAnimFrame: function () {
+ window.cancelAnimationFrame(this.animationFrame)
+ },
+
+ // kicks off the animation - only does something when the queue is currently not active and at least one situation is set
+ start: function () {
+ // dont start if already started
+ if (!this.active && this.situation) {
+ this.active = true
+ this.startCurrent()
+ }
+
+ return this
+ },
+
+ // start the current situation
+ startCurrent: function () {
+ this.situation.start = +new Date() + this.situation.delay / this._speed
+ this.situation.finish = this.situation.start + this.situation.duration / this._speed
+ return this.initAnimations().step()
+ },
+
+ /**
+ * adds a function / Situation to the animation queue
+ * @param fn function / situation to add
+ * @return this
+ */
+ queue: function (fn) {
+ if (typeof fn === 'function' || fn instanceof SVG.Situation) {
+ this.situations.push(fn)
+ }
+
+ if (!this.situation) this.situation = this.situations.shift()
+
+ return this
+ },
+
+ /**
+ * pulls next element from the queue and execute it
+ * @return this
+ */
+ dequeue: function () {
+ // stop current animation
+ this.stop()
+
+ // get next animation from queue
+ this.situation = this.situations.shift()
+
+ if (this.situation) {
+ if (this.situation instanceof SVG.Situation) {
+ this.start()
+ } else {
+ // If it is not a SVG.Situation, then it is a function, we execute it
+ this.situation(this)
+ }
+ }
+
+ return this
+ },
+
+ // updates all animations to the current state of the element
+ // this is important when one property could be changed from another property
+ initAnimations: function () {
+ var i, j, source
+ var s = this.situation
+
+ if (s.init) return this
+
+ for (i in s.animations) {
+ source = this.target()[i]()
+
+ if (!Array.isArray(source)) {
+ source = [source]
+ }
+
+ if (!Array.isArray(s.animations[i])) {
+ s.animations[i] = [s.animations[i]]
+ }
+
+ // if(s.animations[i].length > source.length) {
+ // source.concat = source.concat(s.animations[i].slice(source.length, s.animations[i].length))
+ // }
+
+ for (j = source.length; j--;) {
+ // The condition is because some methods return a normal number instead
+ // of a SVG.Number
+ if (s.animations[i][j] instanceof SVG.Number) {
+ source[j] = new SVG.Number(source[j])
+ }
+
+ s.animations[i][j] = source[j].morph(s.animations[i][j])
+ }
+ }
+
+ for (i in s.attrs) {
+ s.attrs[i] = new SVG.MorphObj(this.target().attr(i), s.attrs[i])
+ }
+
+ for (i in s.styles) {
+ s.styles[i] = new SVG.MorphObj(this.target().css(i), s.styles[i])
+ }
+
+ s.initialTransformation = this.target().matrixify()
+
+ s.init = true
+ return this
+ },
+
+ clearQueue: function () {
+ this.situations = []
+ return this
+ },
+
+ clearCurrent: function () {
+ this.situation = null
+ return this
+ },
+
+ /** stops the animation immediately
+ * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately.
+ * @param clearQueue A Boolean indicating whether to remove queued animation as well.
+ * @return this
+ */
+ stop: function (jumpToEnd, clearQueue) {
+ var active = this.active
+ this.active = false
+
+ if (clearQueue) {
+ this.clearQueue()
+ }
+
+ if (jumpToEnd && this.situation) {
+ // initialize the situation if it was not
+ !active && this.startCurrent()
+ this.atEnd()
+ }
+
+ this.stopAnimFrame()
+
+ return this.clearCurrent()
+ },
+
+ /** resets the element to the state where the current element has started
+ * @return this
+ */
+ reset: function () {
+ if (this.situation) {
+ var temp = this.situation
+ this.stop()
+ this.situation = temp
+ this.atStart()
+ }
+ return this
+ },
+
+ // Stop the currently-running animation, remove all queued animations, and complete all animations for the element.
+ finish: function () {
+ this.stop(true, false)
+
+ while (this.dequeue().situation && this.stop(true, false));
+
+ this.clearQueue().clearCurrent()
+
+ return this
+ },
+
+ // set the internal animation pointer at the start position, before any loops, and updates the visualisation
+ atStart: function () {
+ return this.at(0, true)
+ },
+
+ // set the internal animation pointer at the end position, after all the loops, and updates the visualisation
+ atEnd: function () {
+ if (this.situation.loops === true) {
+ // If in a infinite loop, we end the current iteration
+ this.situation.loops = this.situation.loop + 1
+ }
+
+ if (typeof this.situation.loops === 'number') {
+ // If performing a finite number of loops, we go after all the loops
+ return this.at(this.situation.loops, true)
+ } else {
+ // If no loops, we just go at the end
+ return this.at(1, true)
+ }
+ },
+
+ // set the internal animation pointer to the specified position and updates the visualisation
+ // if isAbsPos is true, pos is treated as an absolute position
+ at: function (pos, isAbsPos) {
+ var durDivSpd = this.situation.duration / this._speed
+
+ this.absPos = pos
+ // If pos is not an absolute position, we convert it into one
+ if (!isAbsPos) {
+ if (this.situation.reversed) this.absPos = 1 - this.absPos
+ this.absPos += this.situation.loop
+ }
+
+ this.situation.start = +new Date() - this.absPos * durDivSpd
+ this.situation.finish = this.situation.start + durDivSpd
+
+ return this.step(true)
+ },
+
+ /**
+ * sets or returns the speed of the animations
+ * @param speed null || Number The new speed of the animations
+ * @return Number || this
+ */
+ speed: function (speed) {
+ if (speed === 0) return this.pause()
+
+ if (speed) {
+ this._speed = speed
+ // We use an absolute position here so that speed can affect the delay before the animation
+ return this.at(this.absPos, true)
+ } else return this._speed
+ },
+
+ // Make loopable
+ loop: function (times, reverse) {
+ var c = this.last()
+
+ // store total loops
+ c.loops = (times != null) ? times : true
+ c.loop = 0
+
+ if (reverse) c.reversing = true
+ return this
+ },
+
+ // pauses the animation
+ pause: function () {
+ this.paused = true
+ this.stopAnimFrame()
+
+ return this
+ },
+
+ // unpause the animation
+ play: function () {
+ if (!this.paused) return this
+ this.paused = false
+ // We use an absolute position here so that the delay before the animation can be paused
+ return this.at(this.absPos, true)
+ },
+
+ /**
+ * toggle or set the direction of the animation
+ * true sets direction to backwards while false sets it to forwards
+ * @param reversed Boolean indicating whether to reverse the animation or not (default: toggle the reverse status)
+ * @return this
+ */
+ reverse: function (reversed) {
+ var c = this.last()
+
+ if (typeof reversed === 'undefined') c.reversed = !c.reversed
+ else c.reversed = reversed
+
+ return this
+ },
+
+ /**
+ * returns a float from 0-1 indicating the progress of the current animation
+ * @param eased Boolean indicating whether the returned position should be eased or not
+ * @return number
+ */
+ progress: function (easeIt) {
+ return easeIt ? this.situation.ease(this.pos) : this.pos
+ },
+
+ /**
+ * adds a callback function which is called when the current animation is finished
+ * @param fn Function which should be executed as callback
+ * @return number
+ */
+ after: function (fn) {
+ var c = this.last()
+ function wrapper (e) {
+ if (e.detail.situation === c) {
+ fn.call(this, c)
+ this.off('finished.fx', wrapper) // prevent memory leak
+ }
+ }
+
+ this.target().on('finished.fx', wrapper)
+
+ return this._callStart()
+ },
+
+ // adds a callback which is called whenever one animation step is performed
+ during: function (fn) {
+ var c = this.last()
+ function wrapper (e) {
+ if (e.detail.situation === c) {
+ fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, c)
+ }
+ }
+
+ // see above
+ this.target().off('during.fx', wrapper).on('during.fx', wrapper)
+
+ this.after(function () {
+ this.off('during.fx', wrapper)
+ })
+
+ return this._callStart()
+ },
+
+ // calls after ALL animations in the queue are finished
+ afterAll: function (fn) {
+ var wrapper = function wrapper (e) {
+ fn.call(this)
+ this.off('allfinished.fx', wrapper)
+ }
+
+ // see above
+ this.target().off('allfinished.fx', wrapper).on('allfinished.fx', wrapper)
+
+ return this._callStart()
+ },
+
+ // calls on every animation step for all animations
+ duringAll: function (fn) {
+ var wrapper = function (e) {
+ fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, e.detail.situation)
+ }
+
+ this.target().off('during.fx', wrapper).on('during.fx', wrapper)
+
+ this.afterAll(function () {
+ this.off('during.fx', wrapper)
+ })
+
+ return this._callStart()
+ },
+
+ last: function () {
+ return this.situations.length ? this.situations[this.situations.length - 1] : this.situation
+ },
+
+ // adds one property to the animations
+ add: function (method, args, type) {
+ this.last()[type || 'animations'][method] = args
+ return this._callStart()
+ },
+
+ /** perform one step of the animation
+ * @param ignoreTime Boolean indicating whether to ignore time and use position directly or recalculate position based on time
+ * @return this
+ */
+ step: function (ignoreTime) {
+ // convert current time to an absolute position
+ if (!ignoreTime) this.absPos = this.timeToAbsPos(+new Date())
+
+ // This part convert an absolute position to a position
+ if (this.situation.loops !== false) {
+ var absPos, absPosInt, lastLoop
+
+ // If the absolute position is below 0, we just treat it as if it was 0
+ absPos = Math.max(this.absPos, 0)
+ absPosInt = Math.floor(absPos)
+
+ if (this.situation.loops === true || absPosInt < this.situation.loops) {
+ this.pos = absPos - absPosInt
+ lastLoop = this.situation.loop
+ this.situation.loop = absPosInt
+ } else {
+ this.absPos = this.situation.loops
+ this.pos = 1
+ // The -1 here is because we don't want to toggle reversed when all the loops have been completed
+ lastLoop = this.situation.loop - 1
+ this.situation.loop = this.situation.loops
+ }
+
+ if (this.situation.reversing) {
+ // Toggle reversed if an odd number of loops as occured since the last call of step
+ this.situation.reversed = this.situation.reversed !== Boolean((this.situation.loop - lastLoop) % 2)
+ }
+ } else {
+ // If there are no loop, the absolute position must not be above 1
+ this.absPos = Math.min(this.absPos, 1)
+ this.pos = this.absPos
+ }
+
+ // while the absolute position can be below 0, the position must not be below 0
+ if (this.pos < 0) this.pos = 0
+
+ if (this.situation.reversed) this.pos = 1 - this.pos
+
+ // apply easing
+ var eased = this.situation.ease(this.pos)
+
+ // call once-callbacks
+ for (var i in this.situation.once) {
+ if (i > this.lastPos && i <= eased) {
+ this.situation.once[i].call(this.target(), this.pos, eased)
+ delete this.situation.once[i]
+ }
+ }
+
+ // fire during callback with position, eased position and current situation as parameter
+ if (this.active) this.target().fire('during', {pos: this.pos, eased: eased, fx: this, situation: this.situation})
+
+ // the user may call stop or finish in the during callback
+ // so make sure that we still have a valid situation
+ if (!this.situation) {
+ return this
+ }
+
+ // apply the actual animation to every property
+ this.eachAt()
+
+ // do final code when situation is finished
+ if ((this.pos === 1 && !this.situation.reversed) || (this.situation.reversed && this.pos === 0)) {
+ // stop animation callback
+ this.stopAnimFrame()
+
+ // fire finished callback with current situation as parameter
+ this.target().fire('finished', {fx: this, situation: this.situation})
+
+ if (!this.situations.length) {
+ this.target().fire('allfinished')
+
+ // Recheck the length since the user may call animate in the afterAll callback
+ if (!this.situations.length) {
+ this.target().off('.fx') // there shouldnt be any binding left, but to make sure...
+ this.active = false
+ }
+ }
+
+ // start next animation
+ if (this.active) this.dequeue()
+ else this.clearCurrent()
+ } else if (!this.paused && this.active) {
+ // we continue animating when we are not at the end
+ this.startAnimFrame()
+ }
+
+ // save last eased position for once callback triggering
+ this.lastPos = eased
+ return this
+ },
+
+ // calculates the step for every property and calls block with it
+ eachAt: function () {
+ var i, len, at
+ var self = this
+ var target = this.target()
+ var s = this.situation
+
+ // apply animations which can be called trough a method
+ for (i in s.animations) {
+ at = [].concat(s.animations[i]).map(function (el) {
+ return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
+ })
+
+ target[i].apply(target, at)
+ }
+
+ // apply animation which has to be applied with attr()
+ for (i in s.attrs) {
+ at = [i].concat(s.attrs[i]).map(function (el) {
+ return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
+ })
+
+ target.attr.apply(target, at)
+ }
+
+ // apply animation which has to be applied with css()
+ for (i in s.styles) {
+ at = [i].concat(s.styles[i]).map(function (el) {
+ return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
+ })
+
+ target.css.apply(target, at)
+ }
+
+ // animate initialTransformation which has to be chained
+ if (s.transforms.length) {
+ // get initial initialTransformation
+ at = s.initialTransformation
+ for (i = 0, len = s.transforms.length; i < len; i++) {
+ // get next transformation in chain
+ var a = s.transforms[i]
+
+ // multiply matrix directly
+ if (a instanceof SVG.Matrix) {
+ if (a.relative) {
+ at = at.multiply(new SVG.Matrix().morph(a).at(s.ease(this.pos)))
+ } else {
+ at = at.morph(a).at(s.ease(this.pos))
+ }
+ continue
+ }
+
+ // when transformation is absolute we have to reset the needed transformation first
+ if (!a.relative) {
+ a.undo(at.extract())
+ }
+
+ // and reapply it after
+ at = at.multiply(a.at(s.ease(this.pos)))
+ }
+
+ // set new matrix on element
+ target.matrix(at)
+ }
+
+ return this
+ },
+
+ // adds an once-callback which is called at a specific position and never again
+ once: function (pos, fn, isEased) {
+ var c = this.last()
+ if (!isEased) pos = c.ease(pos)
+
+ c.once[pos] = fn
+
+ return this
+ },
+
+ _callStart: function () {
+ setTimeout(function () { this.start() }.bind(this), 0)
+ return this
+ }
+
+ },
+
+ parent: SVG.Element,
+
+ // Add method to parent elements
+ construct: {
+ // Get fx module or create a new one, then animate with given duration and ease
+ animate: function (o, ease, delay) {
+ return (this.fx || (this.fx = new SVG.FX(this))).animate(o, ease, delay)
+ },
+ delay: function (delay) {
+ return (this.fx || (this.fx = new SVG.FX(this))).delay(delay)
+ },
+ stop: function (jumpToEnd, clearQueue) {
+ if (this.fx) {
+ this.fx.stop(jumpToEnd, clearQueue)
+ }
+
+ return this
+ },
+ finish: function () {
+ if (this.fx) {
+ this.fx.finish()
+ }
+
+ return this
+ },
+ // Pause current animation
+ pause: function () {
+ if (this.fx) {
+ this.fx.pause()
+ }
+
+ return this
+ },
+ // Play paused current animation
+ play: function () {
+ if (this.fx) { this.fx.play() }
+
+ return this
+ },
+ // Set/Get the speed of the animations
+ speed: function (speed) {
+ if (this.fx) {
+ if (speed == null) { return this.fx.speed() } else { this.fx.speed(speed) }
+ }
+
+ return this
+ }
+ }
+
})
-SVG.Mask = SVG.invent({
- // Initialize node
- create: 'mask'
-
- // Inherit from
-, inherit: SVG.Container
-
- // Add class methods
-, extend: {
- // Unmask all masked elements and remove itself
- remove: function() {
- // unmask all targets
- this.targets().forEach(function(el) {
- el.unmask()
- })
-
- // remove mask from parent
- return SVG.Element.prototype.remove.call(this)
- }
-
- , targets: function() {
- return SVG.select('svg [mask*="' + this.id() + '"]')
- }
- }
-
- // 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) {
- // use given mask or create a new one
- var masker = element instanceof SVG.Mask ? element : this.parent().mask().add(element)
-
- // apply mask
- return this.attr('mask', 'url("#' + masker.id() + '")')
- }
- // Unmask element
-, unmask: function() {
- return this.attr('mask', null)
- }
-, masker: function() {
- return this.reference('mask')
- }
-})
-
-SVG.ClipPath = SVG.invent({
- // Initialize node
- create: 'clipPath'
-
- // Inherit from
-, inherit: SVG.Container
-
- // Add class methods
-, extend: {
- // Unclip all clipped elements and remove itself
- remove: function() {
- // unclip all targets
- this.targets().forEach(function(el) {
- el.unclip()
- })
-
- // remove clipPath from parent
- return SVG.Element.prototype.remove.call(this)
- }
-
- , targets: function() {
- return SVG.select('svg [clip-path*="' +this.id() +'"]')
- }
- }
-
- // Add parent method
-, construct: {
- // Create clipping element
- clip: function() {
- return this.defs().put(new SVG.ClipPath)
- }
- }
-})
-
-//
-SVG.extend(SVG.Element, {
- // Distribute clipPath to svg element
- clipWith: function(element) {
- // use given clip or create a new one
- var clipper = element instanceof SVG.ClipPath ? element : this.parent().clip().add(element)
-
- // apply mask
- return this.attr('clip-path', 'url("#' + clipper.id() + '")')
- }
- // Unclip element
-, unclip: function() {
- return this.attr('clip-path', null)
- }
-, clipper: function() {
- return this.reference('clip-path')
- }
-
+
+// MorphObj is used whenever no morphable object is given
+SVG.MorphObj = SVG.invent({
+
+ create: function (from, to) {
+ // prepare color for morphing
+ if (SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
+ // prepare value list for morphing
+ if (SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
+ // prepare number for morphing
+ if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
+
+ // prepare for plain morphing
+ this.value = from
+ this.destination = to
+ },
+
+ extend: {
+ at: function (pos, real) {
+ return real < 1 ? this.value : this.destination
+ },
+
+ valueOf: function () {
+ return this.value
+ }
+ }
+
})
-SVG.Gradient = SVG.invent({
- // Initialize node
- create: function(type) {
- this.constructor.call(this, typeof type == 'object' ? type : SVG.create(type + 'Gradient'))
- }
-
- // Inherit from
-, inherit: SVG.Container
-
- // Add class methods
-, extend: {
- // Add a color stop
- stop: function(offset, color, opacity) {
- return this.put(new SVG.Stop).update(offset, color, opacity)
- }
- // Update gradient
- , update: function(block) {
- // remove all stops
- this.clear()
-
- // invoke passed block
- if (typeof block == 'function')
- block.call(this, this)
-
- return this
- }
- // Return the fill id
- , url: function() {
- return 'url(#' + this.id() + ')'
- }
- // Alias string convertion to fill
- , toString: function() {
- return this.url()
- }
- // custom attr to handle transform
- , attr: function(a, b, c) {
- if(a == 'transform') a = 'gradientTransform'
- return SVG.Container.prototype.attr.call(this, a, b, c)
- }
- }
-
- // Add parent method
-, construct: {
- // Create gradient element in defs
- gradient: function(type, block) {
- return this.defs().gradient(type, block)
- }
- }
-})
-
-// Add animatable methods to both gradient and fx module
-SVG.extend([SVG.Gradient, SVG.FX], {
- // From position
- from: function(x, y) {
- return (this._target || this).type == 'radialGradient' ?
- 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._target || this).type == 'radialGradient' ?
- this.attr({ cx: new SVG.Number(x), cy: new SVG.Number(y) }) :
- this.attr({ x2: new SVG.Number(x), y2: new SVG.Number(y) })
- }
-})
-
-// Base gradient generation
-SVG.extend(SVG.Defs, {
- // define gradient
- gradient: function(type, block) {
- return this.put(new SVG.Gradient(type)).update(block)
- }
-
-})
-
-SVG.Stop = SVG.invent({
- // Initialize node
- create: 'stop'
-
- // Inherit from
-, inherit: SVG.Element
-
- // Add class methods
-, extend: {
- // add color stops
- update: function(o) {
- if (typeof o == 'number' || o instanceof SVG.Number) {
- o = {
- offset: arguments[0]
- , color: arguments[1]
- , opacity: arguments[2]
- }
- }
-
- // 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
- }
- }
-
-})
-
-SVG.Pattern = SVG.invent({
- // Initialize node
- create: 'pattern'
-
- // Inherit from
-, inherit: SVG.Container
-
- // Add class methods
-, extend: {
- // Return the fill id
- url: function() {
- return 'url(#' + this.id() + ')'
- }
- // Update pattern by rebuilding
- , update: function(block) {
- // remove content
- this.clear()
-
- // invoke passed block
- if (typeof block == 'function')
- block.call(this, this)
-
- return this
- }
- // Alias string convertion to fill
- , toString: function() {
- return this.url()
- }
- // custom attr to handle transform
- , attr: function(a, b, c) {
- if(a == 'transform') a = 'patternTransform'
- return SVG.Container.prototype.attr.call(this, a, b, c)
- }
-
- }
-
- // Add parent method
-, construct: {
- // Create pattern element in defs
- pattern: function(width, height, block) {
- return this.defs().pattern(width, height, block)
- }
- }
-})
-
-SVG.extend(SVG.Defs, {
- // Define gradient
- pattern: function(width, height, block) {
- return this.put(new SVG.Pattern).update(block).attr({
- x: 0
- , y: 0
- , width: width
- , height: height
- , patternUnits: 'userSpaceOnUse'
- })
- }
-
+
+SVG.extend(SVG.FX, {
+ // Add animatable attributes
+ attr: function (a, v, relative) {
+ // apply attributes individually
+ if (typeof a === 'object') {
+ for (var key in a) {
+ this.attr(key, a[key])
+ }
+ } else {
+ this.add(a, v, 'attrs')
+ }
+
+ return this
+ },
+ // Add animatable styles
+ css: function (s, v) {
+ if (typeof s === 'object') {
+ for (var key in s) {
+ this.css(key, s[key])
+ }
+ } else {
+ this.add(s, v, 'styles')
+ }
+
+ return this
+ },
+ // Animatable x-axis
+ x: function (x, relative) {
+ if (this.target() instanceof SVG.G) {
+ this.transform({x: x}, relative)
+ return this
+ }
+
+ var num = new SVG.Number(x)
+ num.relative = relative
+ return this.add('x', num)
+ },
+ // Animatable y-axis
+ y: function (y, relative) {
+ if (this.target() instanceof SVG.G) {
+ this.transform({y: y}, relative)
+ return this
+ }
+
+ var num = new SVG.Number(y)
+ num.relative = relative
+ return this.add('y', num)
+ },
+ // Animatable center x-axis
+ cx: function (x) {
+ return this.add('cx', new SVG.Number(x))
+ },
+ // Animatable center y-axis
+ cy: function (y) {
+ return this.add('cy', new SVG.Number(y))
+ },
+ // Add animatable move
+ move: function (x, y) {
+ return this.x(x).y(y)
+ },
+ // Add animatable center
+ center: function (x, y) {
+ return this.cx(x).cy(y)
+ },
+ // Add animatable size
+ size: function (width, height) {
+ if (this.target() instanceof SVG.Text) {
+ // animate font size for Text elements
+ this.attr('font-size', width)
+ } else {
+ // animate bbox based size for all other elements
+ var box
+
+ if (!width || !height) {
+ box = this.target().bbox()
+ }
+
+ if (!width) {
+ width = box.width / box.height * height
+ }
+
+ if (!height) {
+ height = box.height / box.width * width
+ }
+
+ this.add('width', new SVG.Number(width))
+ .add('height', new SVG.Number(height))
+ }
+
+ return this
+ },
+ // Add animatable width
+ width: function (width) {
+ return this.add('width', new SVG.Number(width))
+ },
+ // Add animatable height
+ height: function (height) {
+ return this.add('height', new SVG.Number(height))
+ },
+ // Add animatable plot
+ plot: function (a, b, c, d) {
+ // Lines can be plotted with 4 arguments
+ if (arguments.length === 4) {
+ return this.plot([a, b, c, d])
+ }
+
+ return this.add('plot', new (this.target().MorphArray)(a))
+ },
+ // Add leading method
+ leading: function (value) {
+ return this.target().leading
+ ? this.add('leading', new SVG.Number(value))
+ : this
+ },
+ // Add animatable viewbox
+ viewbox: function (x, y, width, height) {
+ if (this.target() instanceof SVG.Container) {
+ this.add('viewbox', new SVG.Box(x, y, width, height))
+ }
+
+ return this
+ },
+ update: function (o) {
+ if (this.target() instanceof SVG.Stop) {
+ if (typeof o === 'number' || o instanceof SVG.Number) {
+ return this.update({
+ offset: arguments[0],
+ color: arguments[1],
+ opacity: arguments[2]
+ })
+ }
+
+ 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', o.offset)
+ }
+
+ return this
+ }
})
-SVG.Doc = SVG.invent({
- // Initialize node
- create: function(node) {
- this.constructor.call(this, node || SVG.create('svg'))
-
- // set svg element attributes and ensure defs node
- this.namespace().defs()
- }
-
- // Inherit from
-, inherit: SVG.Container
-
- // Add class methods
-, extend: {
- // Add namespaces
- namespace: function() {
- return this
- .attr({ xmlns: SVG.ns, version: '1.1' })
- .attr('xmlns:xlink', SVG.xlink, SVG.xmlns)
- .attr('xmlns:svgjs', SVG.svgjs, SVG.xmlns)
- }
- // Creates and returns defs element
- , defs: function() {
- return SVG.adopt(this.node.getElementsByTagName('defs')[0]) || this.put(new SVG.Defs())
- }
- // custom parent method
- , parent: function() {
- return this.node.parentNode.nodeName == '#document' ? null : this.node.parentNode
- }
- // Removes the doc from the DOM
- , remove: function() {
- if(this.parent()) {
- this.parent().removeChild(this.node)
- }
-
- return this
- }
- , clear: function() {
- // remove children
- while(this.node.hasChildNodes())
- this.node.removeChild(this.node.lastChild)
- return this
- }
- , toNested: function() {
- var el = SVG.create('svg')
- this.node.instance = null
- el.appendChild(this.node)
-
- return SVG.adopt(this.node)
- }
- }
-
-})
-
-SVG.Shape = SVG.invent({
- // Initialize node
- create: function(node) {
- this.constructor.call(this, node)
- }
-
- // Inherit from
-, inherit: SVG.Element
-
-})
-
-
-SVG.Bare = SVG.invent({
- // Initialize
- create: function(element, inherit) {
- // construct element
- this.constructor.call(this, SVG.create(element))
-
- // inherit custom methods
- if (inherit)
- for (var method in inherit.prototype)
- if (typeof inherit.prototype[method] === 'function')
- this[method] = inherit.prototype[method]
- }
-
- // Inherit from
-, inherit: SVG.Element
-
- // Add methods
-, extend: {
- // Insert some plain text
- words: function(text) {
- // remove contents
- while (this.node.hasChildNodes())
- this.node.removeChild(this.node.lastChild)
-
- // create text node
- this.node.appendChild(document.createTextNode(text))
-
- return this
- }
- }
-})
-
-
-SVG.extend(SVG.Parent, {
- // Create an element that is not described by SVG.js
- element: function(element, inherit) {
- return this.put(new SVG.Bare(element, inherit))
- }
-})
-
-SVG.Symbol = SVG.invent({
- // Initialize node
- create: 'symbol'
-
- // Inherit from
-, inherit: SVG.Container
-
-, construct: {
- // create symbol
- symbol: function() {
- return this.put(new SVG.Symbol)
- }
- }
-})
-
-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, file) {
- // Set lined element
- return this.attr('href', (file || '') + '#' + element, SVG.xlink)
- }
- }
-
- // Add parent method
-, construct: {
- // Create a use element
- use: function(element, file) {
- return this.put(new SVG.Use).element(element, file)
- }
- }
-})
-
-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)
- }
- }
+
+/* global abcdef, arrayToMatrix, deltaTransformPoint, parseMatrix */
+
+SVG.Matrix = SVG.invent({
+ // Initialize
+ create: function (source) {
+ var base = arrayToMatrix([1, 0, 0, 1, 0, 0])
+ var i
+
+ // ensure source as object
+ source = source instanceof SVG.Element ? source.matrixify()
+ : typeof source === 'string' ? arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat))
+ : arguments.length === 6 ? arrayToMatrix([].slice.call(arguments))
+ : Array.isArray(source) ? arrayToMatrix(source)
+ : typeof source === 'object' ? source
+ : base
+
+ // merge source
+ for (i = abcdef.length - 1; i >= 0; --i) {
+ this[abcdef[i]] = source[abcdef[i]] != null
+ ? source[abcdef[i]]
+ : base[abcdef[i]]
+ }
+ },
+
+ // Add methods
+ extend: {
+ // Extract individual transformations
+ extract: function () {
+ // find delta transform points
+ var px = deltaTransformPoint(this, 0, 1)
+ var py = deltaTransformPoint(this, 1, 0)
+ var skewX = 180 / Math.PI * Math.atan2(px.y, px.x) - 90
+
+ return {
+ // translation
+ x: this.e,
+ y: this.f,
+ transformedX: (this.e * Math.cos(skewX * Math.PI / 180) + this.f * Math.sin(skewX * Math.PI / 180)) / Math.sqrt(this.a * this.a + this.b * this.b),
+ transformedY: (this.f * Math.cos(skewX * Math.PI / 180) + this.e * Math.sin(-skewX * Math.PI / 180)) / Math.sqrt(this.c * this.c + this.d * this.d),
+ // skew
+ skewX: -skewX,
+ skewY: 180 / Math.PI * Math.atan2(py.y, py.x),
+ // scale
+ scaleX: Math.sqrt(this.a * this.a + this.b * this.b),
+ scaleY: Math.sqrt(this.c * this.c + this.d * this.d),
+ // rotation
+ rotation: skewX,
+ a: this.a,
+ b: this.b,
+ c: this.c,
+ d: this.d,
+ e: this.e,
+ f: this.f,
+ matrix: new SVG.Matrix(this)
+ }
+ },
+ // Clone matrix
+ clone: function () {
+ return new SVG.Matrix(this)
+ },
+ // Morph one matrix into another
+ morph: function (matrix) {
+ // store new destination
+ this.destination = new SVG.Matrix(matrix)
+
+ return this
+ },
+ // Get morphed matrix at a given position
+ at: function (pos) {
+ // make sure a destination is defined
+ if (!this.destination) return this
+
+ // calculate morphed matrix at a given position
+ var matrix = new SVG.Matrix({
+ a: this.a + (this.destination.a - this.a) * pos,
+ b: this.b + (this.destination.b - this.b) * pos,
+ c: this.c + (this.destination.c - this.c) * pos,
+ d: this.d + (this.destination.d - this.d) * pos,
+ e: this.e + (this.destination.e - this.e) * pos,
+ f: this.f + (this.destination.f - this.f) * pos
+ })
+
+ return matrix
+ },
+ // Multiplies by given matrix
+ multiply: function (matrix) {
+ return new SVG.Matrix(this.native().multiply(parseMatrix(matrix).native()))
+ },
+ // Inverses matrix
+ inverse: function () {
+ return new SVG.Matrix(this.native().inverse())
+ },
+ // Translate matrix
+ translate: function (x, y) {
+ return new SVG.Matrix(this.native().translate(x || 0, y || 0))
+ },
+ // Scale matrix
+ scale: function (x, y, cx, cy) {
+ // support uniformal scale
+ if (arguments.length === 1) {
+ y = x
+ } else if (arguments.length === 3) {
+ cy = cx
+ cx = y
+ y = x
+ }
+
+ return this.around(cx, cy, new SVG.Matrix(x, 0, 0, y, 0, 0))
+ },
+ // Rotate matrix
+ rotate: function (r, cx, cy) {
+ // convert degrees to radians
+ r = SVG.utils.radians(r)
+
+ return this.around(cx, cy, new SVG.Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0))
+ },
+ // Flip matrix on x or y, at a given offset
+ flip: function (a, o) {
+ return a === 'x' ? this.scale(-1, 1, o, 0)
+ : a === 'y' ? this.scale(1, -1, 0, o)
+ : this.scale(-1, -1, a, o != null ? o : a)
+ },
+ // Skew
+ skew: function (x, y, cx, cy) {
+ // support uniformal skew
+ if (arguments.length === 1) {
+ y = x
+ } else if (arguments.length === 3) {
+ cy = cx
+ cx = y
+ y = x
+ }
+
+ // convert degrees to radians
+ x = SVG.utils.radians(x)
+ y = SVG.utils.radians(y)
+
+ return this.around(cx, cy, new SVG.Matrix(1, Math.tan(y), Math.tan(x), 1, 0, 0))
+ },
+ // SkewX
+ skewX: function (x, cx, cy) {
+ return this.skew(x, 0, cx, cy)
+ },
+ // SkewY
+ skewY: function (y, cx, cy) {
+ return this.skew(0, y, cx, cy)
+ },
+ // Transform around a center point
+ around: function (cx, cy, matrix) {
+ return this
+ .multiply(new SVG.Matrix(1, 0, 0, 1, cx || 0, cy || 0))
+ .multiply(matrix)
+ .multiply(new SVG.Matrix(1, 0, 0, 1, -cx || 0, -cy || 0))
+ },
+ // Convert to native SVGMatrix
+ native: function () {
+ // create new matrix
+ var matrix = SVG.parser.nodes.svg.node.createSVGMatrix()
+
+ // update with current values
+ for (var i = abcdef.length - 1; i >= 0; i--) {
+ matrix[abcdef[i]] = this[abcdef[i]]
+ }
+
+ return matrix
+ },
+ // Convert matrix to string
+ toString: function () {
+ return 'matrix(' + this.a + ',' + this.b + ',' + this.c + ',' + this.d + ',' + this.e + ',' + this.f + ')'
+ }
+ },
+
+ // Define parent
+ parent: SVG.Element,
+
+ // Add parent method
+ construct: {
+ // Get current matrix
+ ctm: function () {
+ return new SVG.Matrix(this.node.getCTM())
+ },
+ // Get current screen matrix
+ screenCTM: function () {
+ /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537
+ This is needed because FF does not return the transformation matrix
+ for the inner coordinate system when getScreenCTM() is called on nested svgs.
+ However all other Browsers do that */
+ if (this instanceof SVG.Nested) {
+ var rect = this.rect(1, 1)
+ var m = rect.node.getScreenCTM()
+ rect.remove()
+ return new SVG.Matrix(m)
+ }
+ return new SVG.Matrix(this.node.getScreenCTM())
+ }
+ }
})
-SVG.Circle = SVG.invent({
- // Initialize node
- create: 'circle'
-
- // Inherit from
-, inherit: SVG.Shape
-
- // Add parent method
-, construct: {
- // Create circle element, based on ellipse
- circle: function(size) {
- return this.put(new SVG.Circle).rx(new SVG.Number(size).divide(2)).move(0, 0)
- }
- }
-})
-
-SVG.extend([SVG.Circle, SVG.FX], {
- // Radius x value
- rx: function(rx) {
- return this.attr('r', rx)
- }
- // Alias radius x value
-, ry: function(ry) {
- return this.rx(ry)
- }
-})
-
-SVG.Ellipse = SVG.invent({
- // Initialize node
- create: 'ellipse'
-
- // Inherit from
-, inherit: SVG.Shape
-
- // Add parent method
-, construct: {
- // Create an ellipse
- ellipse: function(width, height) {
- return this.put(new SVG.Ellipse).size(width, height).move(0, 0)
- }
- }
-})
-
-SVG.extend([SVG.Ellipse, SVG.Rect, SVG.FX], {
- // Radius x value
- rx: function(rx) {
- return this.attr('rx', rx)
- }
- // Radius y value
-, ry: function(ry) {
- return this.attr('ry', ry)
- }
-})
-
-// Add common method
-SVG.extend([SVG.Circle, SVG.Ellipse], {
- // Move over x-axis
- x: function(x) {
- return x == null ? this.cx() - this.rx() : this.cx(x + this.rx())
- }
- // Move over y-axis
- , y: function(y) {
- return y == null ? this.cy() - this.ry() : this.cy(y + this.ry())
- }
- // Move by center over x-axis
- , cx: function(x) {
- return x == null ? this.attr('cx') : this.attr('cx', x)
- }
- // Move by center over y-axis
- , cy: function(y) {
- return y == null ? this.attr('cy') : this.attr('cy', y)
- }
- // Set width of element
- , width: function(width) {
- return width == null ? this.rx() * 2 : this.rx(new SVG.Number(width).divide(2))
- }
- // Set height of element
- , height: function(height) {
- return height == null ? this.ry() * 2 : this.ry(new SVG.Number(height).divide(2))
- }
- // Custom size function
- , size: function(width, height) {
- var p = proportionalSize(this, width, height)
-
- return this
- .rx(new SVG.Number(p.width).divide(2))
- .ry(new SVG.Number(p.height).divide(2))
- }
+
+
+SVG.Point = SVG.invent({
+ // Initialize
+ create: function (x, y) {
+ var base = {x: 0, y: 0}
+ var source
+
+ // ensure source as object
+ source = Array.isArray(x) ? {x: x[0], y: x[1]}
+ : typeof x === 'object' ? {x: x.x, y: x.y}
+ : x != null ? {x: x, y: (y != null ? y : x)}
+ : base // If y has no value, then x is used has its value
+
+ // merge source
+ this.x = source.x
+ this.y = source.y
+ },
+
+ // Add methods
+ extend: {
+ // Clone point
+ clone: function () {
+ return new SVG.Point(this)
+ },
+ // Morph one point into another
+ morph: function (x, y) {
+ // store new destination
+ this.destination = new SVG.Point(x, y)
+
+ return this
+ },
+ // Get morphed point at a given position
+ at: function (pos) {
+ // make sure a destination is defined
+ if (!this.destination) return this
+
+ // calculate morphed matrix at a given position
+ var point = new SVG.Point({
+ x: this.x + (this.destination.x - this.x) * pos,
+ y: this.y + (this.destination.y - this.y) * pos
+ })
+
+ return point
+ },
+ // Convert to native SVGPoint
+ native: function () {
+ // create new point
+ var point = SVG.parser.nodes.svg.node.createSVGPoint()
+
+ // update with current values
+ point.x = this.x
+ point.y = this.y
+
+ return point
+ },
+ // transform point with matrix
+ transform: function (matrix) {
+ return new SVG.Point(this.native().matrixTransform(matrix.native()))
+ }
+ }
})
-SVG.Line = SVG.invent({
- // Initialize node
- create: 'line'
-
- // Inherit from
-, inherit: SVG.Shape
-
- // Add class methods
-, extend: {
- // Get array
- array: function() {
- return new SVG.PointArray([
- [ this.attr('x1'), this.attr('y1') ]
- , [ this.attr('x2'), this.attr('y2') ]
- ])
- }
- // Overwrite native plot() method
- , plot: function(x1, y1, x2, y2) {
- if (x1 == null)
- return this.array()
- else if (typeof y1 !== 'undefined')
- x1 = { x1: x1, y1: y1, x2: x2, y2: y2 }
- else
- x1 = new SVG.PointArray(x1).toLine()
-
- return this.attr(x1)
- }
- // Move by left top corner
- , move: function(x, y) {
- return this.attr(this.array().move(x, y).toLine())
- }
- // Set element size to given width and height
- , size: function(width, height) {
- var p = proportionalSize(this, width, height)
-
- return this.attr(this.array().size(p.width, p.height).toLine())
- }
- }
-
- // Add parent method
-, construct: {
- // Create a line element
- line: function(x1, y1, x2, y2) {
- // make sure plot is called as a setter
- // x1 is not necessarily a number, it can also be an array, a string and a SVG.PointArray
- return SVG.Line.prototype.plot.apply(
- this.put(new SVG.Line)
- , x1 != null ? [x1, y1, x2, y2] : [0, 0, 0, 0]
- )
- }
- }
-})
-
-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) {
- // make sure plot is called as a setter
- return this.put(new SVG.Polyline).plot(p || new SVG.PointArray)
- }
- }
-})
-
-SVG.Polygon = SVG.invent({
- // Initialize node
- create: 'polygon'
-
- // Inherit from
-, inherit: SVG.Shape
-
- // Add parent method
-, construct: {
- // Create a wrapped polygon element
- polygon: function(p) {
- // make sure plot is called as a setter
- return this.put(new SVG.Polygon).plot(p || new SVG.PointArray)
- }
- }
-})
-
-// Add polygon-specific functions
-SVG.extend([SVG.Polyline, SVG.Polygon], {
- // Get array
- array: function() {
- return this._array || (this._array = new SVG.PointArray(this.attr('points')))
- }
- // Plot new path
-, plot: function(p) {
- return (p == null) ?
- this.array() :
- this.clear().attr('points', typeof p == 'string' ? p : (this._array = new SVG.PointArray(p)))
- }
- // Clear array cache
-, clear: function() {
- delete this._array
- return this
- }
- // Move by left top corner
-, move: function(x, y) {
- return this.attr('points', this.array().move(x, y))
- }
- // Set element size to given width and height
-, size: function(width, height) {
- var p = proportionalSize(this, width, height)
-
- return this.attr('points', this.array().size(p.width, p.height))
- }
-
-})
-
-// unify all point to point elements
-SVG.extend([SVG.Line, SVG.Polyline, SVG.Polygon], {
- // Define morphable array
- morphArray: SVG.PointArray
- // 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 width of element
-, width: function(width) {
- var b = this.bbox()
-
- return width == null ? b.width : this.size(width, b.height)
- }
- // Set height of element
-, height: function(height) {
- var b = this.bbox()
-
- return height == null ? b.height : this.size(b.width, height)
- }
+
+SVG.extend(SVG.Element, {
+
+ // Get point
+ point: function (x, y) {
+ return new SVG.Point(x, y).transform(this.screenCTM().inverse())
+ }
+
})
-SVG.Path = SVG.invent({
- // Initialize node
- create: 'path'
-
- // Inherit from
-, inherit: SVG.Shape
-
- // Add class methods
-, extend: {
- // Define morphable array
- morphArray: SVG.PathArray
- // Get array
- , array: function() {
- return this._array || (this._array = new SVG.PathArray(this.attr('d')))
- }
- // Plot new path
- , plot: function(d) {
- return (d == null) ?
- this.array() :
- this.clear().attr('d', typeof d == 'string' ? d : (this._array = new SVG.PathArray(d)))
- }
- // Clear array cache
- , clear: function() {
- delete this._array
- return this
- }
- // 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 = proportionalSize(this, 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)
- }
- }
-
- // Add parent method
-, construct: {
- // Create a wrapped path element
- path: function(d) {
- // make sure plot is called as a setter
- return this.put(new SVG.Path).plot(d || new SVG.PathArray)
- }
- }
-})
-
-SVG.Image = SVG.invent({
- // Initialize node
- create: 'image'
-
- // Inherit from
-, inherit: SVG.Shape
-
- // Add class methods
-, extend: {
- // (re)load image
- load: function(url, callback) {
- if (!url) return this
-
- var img = new window.Image()
-
- SVG.on(img, 'load', function(e) {
- var p = this.parent(SVG.Pattern)
-
- // ensure image size
- if (this.width() == 0 && this.height() == 0)
- this.size(img.width, img.height)
-
- if(p instanceof SVG.Pattern) {
- // ensure pattern size if not set
- if (p.width() == 0 && p.height() == 0)
- p.size(this.width(), this.height())
- }
-
- if(typeof callback == 'function') {
- callback.call(this, {
- width: img.width
- , height: img.height
- , ratio: img.width / img.height
- , url: url
- })
- }
- }, this)
-
- SVG.on(img, 'load error', function() {
- // dont forget to unbind this memory leaking events
- SVG.off(img)
- })
-
- return this.attr('href', (img.src = url), SVG.xlink)
- }
- }
-
- // Add parent method
-, construct: {
- // create image element, load image and set its size
- image: function(source, callback) {
- return this.put(new SVG.Image).size(0, 0).load(source, callback)
- }
- }
-})
-
-SVG.Text = SVG.invent({
- // Initialize node
- create: function(node) {
- this.constructor.call(this, node || SVG.create('text'))
-
- this.dom.leading = new SVG.Number(1.3) // store leading value for rebuilding
- this._rebuild = true // enable automatic updating of dy values
- this._build = false // disable build mode for adding multiple lines
-
- // set default font
- this.attr('font-family', SVG.defaults.attrs['font-family'])
- }
-
- // Inherit from
-, inherit: SVG.Parent
-
- // Add class methods
-, extend: {
- // Move over x-axis
- x: function(x) {
- // act as getter
- if (x == null)
- return this.attr('x')
-
- return this.attr('x', x)
- }
- // Move over y-axis
- , y: function(y) {
- var oy = this.attr('y')
- , o = typeof oy === 'number' ? oy - this.bbox().y : 0
-
- // act as getter
- if (y == null)
- return typeof oy === 'number' ? oy - o : oy
-
- return this.attr('y', typeof y === 'number' ? y + o : y)
- }
- // Move center over x-axis
- , cx: function(x) {
- return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2)
- }
- // Move center over y-axis
- , cy: function(y) {
- return y == null ? this.bbox().cy : this.y(y - this.bbox().height / 2)
- }
- // Set the text content
- , text: function(text) {
- // act as getter
- if (text === undefined){
- var text = ''
- , children = this.node.childNodes
- , firstLine = 0
-
- for(var i = 0, len = children.length; i < len; ++i){
- // skip textPaths - they are no lines
- if(children[i].nodeName == 'textPath') {
- if(i == 0) firstLine = 1
- continue
- }
-
- // add newline if its not the first child and newLined is set to true
- if(i != firstLine && children[i].nodeType != 3 && SVG.adopt(children[i]).dom.newLined == true){
- text += '\n'
- }
-
- // add content of this node
- text += children[i].textContent
- }
-
- return text
- }
-
- // remove existing content
- this.clear().build(true)
-
- if (typeof text === 'function') {
- // call block
- text.call(this, this)
-
- } else {
- // store text and make sure text is not blank
- text = text.split('\n')
-
- // build new lines
- for (var i = 0, il = text.length; i < il; i++)
- this.tspan(text[i]).newLine()
- }
-
- // disable build mode and rebuild lines
- return this.build(false).rebuild()
- }
- // Set font size
- , size: function(size) {
- return this.attr('font-size', size).rebuild()
- }
- // Set / get leading
- , leading: function(value) {
- // act as getter
- if (value == null)
- return this.dom.leading
-
- // act as setter
- this.dom.leading = new SVG.Number(value)
-
- return this.rebuild()
- }
- // Rebuild appearance type
- , rebuild: function(rebuild) {
- // store new rebuild flag if given
- if (typeof rebuild == 'boolean')
- this._rebuild = rebuild
-
- // define position of all lines
- if (this._rebuild) {
- var self = this
- , blankLineOffset = 0
- , dy = this.dom.leading * new SVG.Number(this.attr('font-size'))
-
- this.each(function() {
- if (this.dom.newLined) {
- this.attr('x', self.attr('x'))
-
- if(this.text() == '\n') {
- blankLineOffset += dy
- }else{
- this.attr('dy', dy + blankLineOffset)
- blankLineOffset = 0
- }
- }
- })
-
- this.fire('rebuild')
- }
-
- return this
- }
- // Enable / disable build mode
- , build: function(build) {
- this._build = !!build
- return this
- }
- // overwrite method from parent to set data properly
- , setData: function(o){
- this.dom = o
- this.dom.leading = new SVG.Number(o.leading || 1.3)
- return this
- }
- }
-
- // Add parent method
-, construct: {
- // Create text element
- text: function(text) {
- return this.put(new SVG.Text).text(text)
- }
- // Create plain text element
- , plain: function(text) {
- return this.put(new SVG.Text).plain(text)
- }
- }
-
-})
-
-SVG.Tspan = SVG.invent({
- // Initialize node
- create: 'tspan'
-
- // Inherit from
-, inherit: SVG.Parent
-
- // Add class methods
-, extend: {
- // Set text content
- text: function(text) {
- if(text == null) return this.node.textContent + (this.dom.newLined ? '\n' : '')
-
- typeof text === 'function' ? text.call(this, this) : this.plain(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() {
- // fetch text parent
- var t = this.parent(SVG.Text)
-
- // mark new line
- this.dom.newLined = true
-
- // apply new hy¡n
- return this.dy(t.dom.leading * t.attr('font-size')).attr('x', t.x())
- }
- }
-})
-
-SVG.extend([SVG.Text, SVG.Tspan], {
- // Create plain text node
- plain: function(text) {
- // clear if build mode is disabled
- if (this._build === false)
- this.clear()
-
- // create text node
- this.node.appendChild(document.createTextNode(text))
-
- return this
- }
- // Create a tspan
-, tspan: function(text) {
- var tspan = new SVG.Tspan
-
- // clear if build mode is disabled
- if (!this._build)
- this.clear()
-
- // add new tspan
- this.node.appendChild(tspan.node)
-
- return tspan.text(text)
- }
- // FIXME: Does this also work for textpath?
- // Get length of text element
-, length: function() {
- return this.node.getComputedTextLength()
- }
-})
-
-SVG.TextPath = SVG.invent({
- // Initialize node
- create: 'textPath'
-
- // Inherit from
-, inherit: SVG.Text
-
- // Define parent class
-, parent: SVG.Parent
-
- // Add parent method
-, extend: {
- morphArray: SVG.PathArray
- // return the array of the path track element
- , array: function() {
- var track = this.track()
-
- return track ? track.array() : null
- }
- // Plot path if any
- , plot: function(d) {
- var track = this.track()
- , pathArray = null
-
- if (track) {
- pathArray = track.plot(d)
- }
-
- return (d == null) ? pathArray : this
- }
- // Get the path element
- , track: function() {
- return this.reference('href')
- }
- }
-, construct: {
- textPath: function(text, path) {
- return this.defs().path(path).text(text).addTo(this)
- }
- }
-})
-
-SVG.extend([SVG.Text], {
- // Create path for text to run on
- path: function(track) {
- var path = new SVG.TextPath
-
- // if d is a path, reuse it
- if(!(track instanceof SVG.Path)) {
- // create path element
- track = this.doc().defs().path(track)
- }
-
- // link textPath to path and add content
- path.attr('href', '#' + track, SVG.xlink)
-
- // add textPath element as child node and return textPath
- return this.put(path)
- }
- // Todo: make this plural?
- // Get the textPath children
- , textPath: function() {
- return this.select('textPath')
- }
-})
-
-SVG.extend([SVG.Path], {
- // creates a textPath from this path
- text: function(text) {
- if(text instanceof SVG.Text) {
- var txt = text.text()
- return text.clear().path(this).text(txt)
- }
- return this.parent().put(new SVG.Text()).path(this).text(text)
- }
- // TODO: Maybe add `targets` to get all textPaths associated with this path
-})
-
-SVG.Nested = SVG.invent({
- // Initialize node
- create: 'svg'
-
- // Inherit from
-, inherit: SVG.Container
-
- // Add parent method
-, construct: {
- // Create nested svg document
- nested: function() {
- return this.put(new SVG.Nested)
- }
- }
-})
-
-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 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) {
- var link = new SVG.A
-
- if (typeof url == 'function')
- url.call(link, link)
- else
- link.to(url)
-
- return this.parent().put(link).put(this)
- }
-
+
+SVG.extend(SVG.Element, {
+ // Set svg element attribute
+ attr: function (a, v, n) {
+ // act as full getter
+ 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.isNumber.test(v[n].nodeValue)
+ ? 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 if the first and only argument is not an object
+ v = this.node.getAttribute(a)
+ return v == null ? SVG.defaults.attrs[a]
+ : SVG.regex.isNumber.test(v) ? parseFloat(v)
+ : v
+ } else {
+ // convert image fill and stroke to patterns
+ if (a === 'fill' || a === 'stroke') {
+ if (SVG.regex.isImage.test(v)) {
+ v = this.doc().defs().image(v)
+ }
+
+ if (v instanceof SVG.Image) {
+ v = this.doc().defs().pattern(0, 0, function () {
+ this.add(v)
+ })
+ }
+ }
+
+ // ensure correct numeric values (also accepts NaN and Infinity)
+ if (typeof v === 'number') {
+ v = new SVG.Number(v)
+ } else if (SVG.Color.isColor(v)) {
+ // ensure full hex color
+ v = new SVG.Color(v)
+ } else if (Array.isArray(v)) {
+ // parse array values
+ v = new SVG.Array(v)
+ }
+
+ // if the passed attribute is leading...
+ if (a === 'leading') {
+ // ... call the leading method instead
+ if (this.leading) {
+ this.leading(v)
+ }
+ } else {
+ // set given attribute on node
+ typeof n === 'string' ? this.node.setAttributeNS(n, a, v.toString())
+ : this.node.setAttribute(a, v.toString())
+ }
+
+ // rebuild if required
+ if (this.rebuild && (a === 'font-size' || a === 'x')) {
+ this.rebuild(a, v)
+ }
+ }
+
+ return this
+ }
})
-SVG.Marker = SVG.invent({
- // Initialize node
- create: 'marker'
-
- // Inherit from
-, inherit: SVG.Container
-
- // Add class methods
-, extend: {
- // Set width of element
- width: function(width) {
- return this.attr('markerWidth', width)
- }
- // Set height of element
- , height: function(height) {
- return this.attr('markerHeight', height)
- }
- // Set marker refX and refY
- , ref: function(x, y) {
- return this.attr('refX', x).attr('refY', y)
- }
- // Update marker
- , update: function(block) {
- // remove all content
- this.clear()
-
- // invoke passed block
- if (typeof block == 'function')
- block.call(this, this)
-
- return this
- }
- // Return the fill id
- , toString: function() {
- return 'url(#' + this.id() + ')'
- }
- }
-
- // Add parent method
-, construct: {
- marker: function(width, height, block) {
- // Create marker element in defs
- return this.defs().marker(width, height, block)
- }
- }
-
-})
-
-SVG.extend(SVG.Defs, {
- // Create marker
- marker: function(width, height, block) {
- // Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto
- return this.put(new SVG.Marker)
- .size(width, height)
- .ref(width / 2, height / 2)
- .viewbox(0, 0, width, height)
- .attr('orient', 'auto')
- .update(block)
- }
-
-})
-
-SVG.extend([SVG.Line, SVG.Polyline, SVG.Polygon, SVG.Path], {
- // Create and attach markers
- marker: function(marker, width, height, block) {
- var attr = ['marker']
-
- // Build attribute name
- if (marker != 'all') attr.push(marker)
- attr = attr.join('-')
-
- // Set marker attribute
- marker = arguments[1] instanceof SVG.Marker ?
- arguments[1] :
- this.doc().marker(width, height, block)
-
- return this.attr(attr, marker)
- }
-
+
+/* global ensureCentre, capitalize, arrayToMatrix */
+
+SVG.extend(SVG.Element, {
+ // Add transformations
+ transform: function (o, relative) {
+ // get target in case of the fx module, otherwise reference this
+ var target = this
+ var matrix, bbox
+
+ // act as a getter
+ if (typeof o !== 'object') {
+ // get current matrix
+ matrix = new SVG.Matrix(target).extract()
+
+ return typeof o === 'string' ? matrix[o] : matrix
+ }
+
+ // get current matrix
+ matrix = new SVG.Matrix(target)
+
+ // ensure relative flag
+ relative = !!relative || !!o.relative
+
+ // act on matrix
+ if (o.a != null) {
+ matrix = relative
+ ? matrix.multiply(new SVG.Matrix(o))
+ : new SVG.Matrix(o)
+
+ // act on rotation
+ } else if (o.rotation != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // apply transformation
+ matrix = relative
+ ? matrix.rotate(o.rotation, o.cx, o.cy)
+ : matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy)
+
+ // act on scale
+ } else if (o.scale != null || o.scaleX != null || o.scaleY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure scale values on both axes
+ o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
+ o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
+
+ if (!relative) {
+ // absolute; multiply inversed values
+ var e = matrix.extract()
+ o.scaleX = o.scaleX * 1 / e.scaleX
+ o.scaleY = o.scaleY * 1 / e.scaleY
+ }
+
+ matrix = matrix.scale(o.scaleX, o.scaleY, o.cx, o.cy)
+
+ // act on skew
+ } else if (o.skew != null || o.skewX != null || o.skewY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure skew values on both axes
+ o.skewX = o.skew != null ? o.skew : o.skewX != null ? o.skewX : 0
+ o.skewY = o.skew != null ? o.skew : o.skewY != null ? o.skewY : 0
+
+ if (!relative) {
+ // absolute; reset skew values
+ var el = matrix.extract()
+ matrix = matrix.multiply(new SVG.Matrix().skew(el.skewX, el.skewY, el.cx, el.cy).inverse())
+ }
+
+ matrix = matrix.skew(o.skewX, o.skewY, o.cx, o.cy)
+
+ // act on flip
+ } else if (o.flip) {
+ if (o.flip === 'x' || o.flip === 'y') {
+ o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset
+ } else {
+ if (o.offset == null) {
+ bbox = target.bbox()
+ o.flip = bbox.cx
+ o.offset = bbox.cy
+ } else {
+ o.flip = o.offset
+ }
+ }
+
+ matrix = new SVG.Matrix().flip(o.flip, o.offset)
+
+ // act on translate
+ } else if (o.x != null || o.y != null) {
+ if (relative) {
+ // relative
+ matrix = matrix.translate(o.x, o.y)
+ } else {
+ // absolute
+ if (o.x != null) matrix.e = o.x
+ if (o.y != null) matrix.f = o.y
+ }
+ }
+
+ return this.attr('transform', matrix)
+ }
})
-// Define list of available attributes for stroke and fill
-var sugar = {
- stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset']
-, fill: ['color', 'opacity', 'rule']
-, prefix: function(t, a) {
- return a == 'color' ? t : t + '-' + a
- }
-}
-
-// Add sugar for fill and stroke
-;['fill', 'stroke'].forEach(function(m) {
- var i, extension = {}
-
- extension[m] = function(o) {
- if (typeof o == 'undefined')
- return this
- if (typeof o == 'string' || SVG.Color.isRgb(o) || (o && typeof o.fill === 'function'))
- this.attr(m, o)
-
- else
- // set all attributes from sugar.fill and sugar.stroke list
- for (i = sugar[m].length - 1; i >= 0; i--)
- if (o[sugar[m][i]] != null)
- this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]])
-
- return this
- }
-
- SVG.extend([SVG.Element, SVG.FX], extension)
-
-})
-
-SVG.extend([SVG.Element, SVG.FX], {
- // Map rotation to transform
- rotate: function(d, cx, cy) {
- return this.transform({ rotation: d, cx: cx, cy: cy })
- }
- // Map skew to transform
-, skew: function(x, y, cx, cy) {
- return arguments.length == 1 || arguments.length == 3 ?
- this.transform({ skew: x, cx: y, cy: cx }) :
- this.transform({ skewX: x, skewY: y, cx: cx, cy: cy })
- }
- // Map scale to transform
-, scale: function(x, y, cx, cy) {
- return arguments.length == 1 || arguments.length == 3 ?
- this.transform({ scale: x, cx: y, cy: cx }) :
- this.transform({ scaleX: x, scaleY: y, cx: cx, cy: cy })
- }
- // Map translate to transform
-, translate: function(x, y) {
- return this.transform({ x: x, y: y })
- }
- // Map flip to transform
-, flip: function(a, o) {
- o = typeof a == 'number' ? a : o
- return this.transform({ flip: a || 'both', offset: o })
- }
- // Map matrix to transform
-, matrix: function(m) {
- return this.attr('transform', new SVG.Matrix(arguments.length == 6 ? [].slice.call(arguments) : m))
- }
- // Opacity
-, opacity: function(value) {
- return this.attr('opacity', value)
- }
- // Relative move over x axis
-, dx: function(x) {
- return this.x(new SVG.Number(x).plus(this instanceof SVG.FX ? 0 : this.x()), true)
- }
- // Relative move over y axis
-, dy: function(y) {
- return this.y(new SVG.Number(y).plus(this instanceof SVG.FX ? 0 : this.y()), true)
- }
- // Relative move over x and y axes
-, dmove: function(x, y) {
- return this.dx(x).dy(y)
- }
-})
-
-SVG.extend([SVG.Rect, SVG.Ellipse, SVG.Circle, SVG.Gradient, SVG.FX], {
- // Add x and y radius
- radius: function(x, y) {
- var type = (this._target || this).type;
- return type == 'radialGradient' || type == 'radialGradient' ?
- this.attr('r', new SVG.Number(x)) :
- this.rx(x).ry(y == null ? x : y)
- }
-})
-
-SVG.extend(SVG.Path, {
- // Get path length
- length: function() {
- return this.node.getTotalLength()
- }
- // Get point at length
-, pointAt: function(length) {
- return new SVG.Point(this.node.getPointAtLength(length))
- }
-})
-
-SVG.extend([SVG.Parent, SVG.Text, SVG.Tspan, SVG.FX], {
- // Set font
- font: function(a, v) {
- if (typeof a == 'object') {
- for (v in a) this.font(v, a[v])
- }
-
- return a == 'leading' ?
- this.leading(v) :
- a == 'anchor' ?
- this.attr('text-anchor', v) :
- a == 'size' || a == 'family' || a == 'weight' || a == 'stretch' || a == 'variant' || a == 'style' ?
- this.attr('font-'+ a, v) :
- this.attr(a, v)
- }
-})
-
-
-SVG.extend(SVG.Element, {
- // Store data values on svg nodes
- data: function(a, v, r) {
- if (typeof a == 'object') {
- for (v in a)
- this.data(v, a[v])
-
- } else if (arguments.length < 2) {
- try {
- return JSON.parse(this.attr('data-' + a))
- } catch(e) {
- return this.attr('data-' + a)
- }
-
- } else {
- this.attr(
- 'data-' + a
- , v === null ?
- null :
- r === true || typeof v === 'string' || typeof v === 'number' ?
- v :
- JSON.stringify(v)
- )
- }
-
- return this
- }
+
+SVG.extend(SVG.FX, {
+ transform: function (o, relative) {
+ // get target in case of the fx module, otherwise reference this
+ var target = this.target()
+ var matrix, bbox
+
+ // act as a getter
+ if (typeof o !== 'object') {
+ // get current matrix
+ matrix = new SVG.Matrix(target).extract()
+ return typeof o === 'string' ? matrix[o] : matrix
+ }
+
+ // ensure relative flag
+ relative = !!relative || !!o.relative
+
+ // act on matrix
+ if (o.a != null) {
+ matrix = new SVG.Matrix(o)
+
+ // act on rotation
+ } else if (o.rotation != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // apply transformation
+ matrix = new SVG.Rotate(o.rotation, o.cx, o.cy)
+
+ // act on scale
+ } else if (o.scale != null || o.scaleX != null || o.scaleY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure scale values on both axes
+ o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
+ o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
+
+ matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy)
+
+ // act on skew
+ } else if (o.skewX != null || o.skewY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure skew values on both axes
+ o.skewX = o.skewX != null ? o.skewX : 0
+ o.skewY = o.skewY != null ? o.skewY : 0
+
+ matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy)
+
+ // act on flip
+ } else if (o.flip) {
+ if (o.flip === 'x' || o.flip === 'y') {
+ o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset
+ } else {
+ if (o.offset == null) {
+ bbox = target.bbox()
+ o.flip = bbox.cx
+ o.offset = bbox.cy
+ } else {
+ o.flip = o.offset
+ }
+ }
+
+ matrix = new SVG.Matrix().flip(o.flip, o.offset)
+
+ // act on translate
+ } else if (o.x != null || o.y != null) {
+ matrix = new SVG.Translate(o.x, o.y)
+ }
+
+ if (!matrix) return this
+
+ matrix.relative = relative
+
+ this.last().transforms.push(matrix)
+
+ return this._callStart()
+ }
})
-SVG.extend(SVG.Element, {
- // Remember arbitrary data
- remember: function(k, v) {
- // remember every item in an object individually
- if (typeof arguments[0] == 'object')
- for (var v in k)
- this.remember(v, k[v])
-
- // retrieve memory
- else if (arguments.length == 1)
- return this.memory()[k]
-
- // store memory
- else
- this.memory()[k] = v
-
- return this
- }
-
- // Erase a given memory
-, forget: function() {
- if (arguments.length == 0)
- this._memory = {}
- else
- for (var i = arguments.length - 1; i >= 0; i--)
- delete this.memory()[arguments[i]]
-
- return this
- }
-
- // Initialize or return local memory object
-, memory: function() {
- return this._memory || (this._memory = {})
- }
-
+
+SVG.extend(SVG.Element, {
+ // Reset all transformations
+ untransform: function () {
+ return this.attr('transform', null)
+ },
+ // merge the whole transformation chain into one matrix and returns it
+ matrixify: function () {
+ var matrix = (this.attr('transform') || '')
+ // split transformations
+ .split(SVG.regex.transforms).slice(0, -1).map(function (str) {
+ // generate key => value pairs
+ var kv = str.trim().split('(')
+ return [kv[0], kv[1].split(SVG.regex.delimiter).map(function (str) { return parseFloat(str) })]
+ })
+ // merge every transformation into one matrix
+ .reduce(function (matrix, transform) {
+ if (transform[0] === 'matrix') return matrix.multiply(arrayToMatrix(transform[1]))
+ return matrix[transform[0]].apply(matrix, transform[1])
+ }, new SVG.Matrix())
+
+ return matrix
+ },
+ // add an element to another parent without changing the visual representation on the screen
+ toParent: function (parent) {
+ if (this === parent) return this
+ var ctm = this.screenCTM()
+ var pCtm = parent.screenCTM().inverse()
+
+ this.addTo(parent).untransform().transform(pCtm.multiply(ctm))
+
+ return this
+ },
+ // same as above with parent equals root-svg
+ toDoc: function () {
+ return this.toParent(this.doc())
+ }
+
})
-// Method for getting an element by id
-SVG.get = function(id) {
- var node = document.getElementById(idFromReference(id) || id)
- return SVG.adopt(node)
-}
-
-// Select elements by query string
-SVG.select = function(query, parent) {
- return SVG.utils.map((parent || document).querySelectorAll(query), function(node) {
- return SVG.adopt(node)
- })
-}
-
-SVG.$$ = function(query, parent) {
- return SVG.utils.map((parent || document).querySelectorAll(query), function(node) {
- return SVG.adopt(node)
- })
-}
-
-SVG.$ = function(query, parent) {
- return SVG.adopt((parent || document).querySelector(query))
-}
-
-SVG.extend(SVG.Parent, {
- // Scoped select method
- select: function(query) {
- return SVG.select(query, this.node)
- }
-})
-
-function createElement(element, makeNested) {
- if(element instanceof SVG.Element) return element
-
- if(typeof element == 'object') {
- return SVG.adopt(element)
- }
-
- if(element == null) {
- return new SVG.Doc()
- }
-
- if(typeof element == 'string' && element.charAt(0) != '<') {
- return SVG.adopt(document.querySelector(element))
- }
-
- var node = SVG.create('svg')
- node.innerHTML = element
-
- element = SVG.adopt(node.firstElementChild)
-
- return element
-}
-
-function isNulledBox(box) {
- return !box.w && !box.h && !box.x && !box.y
-}
-
-function domContains(node) {
- return (document.documentElement.contains || function(node) {
- // This is IE - it does not support contains() for top-level SVGs
- while (node.parentNode){
- node = node.parentNode;
- }
- return node == document
- }).call(document.documentElement, node)
-}
-
-function pathRegReplace(a, b, c, d) {
- return c + d.replace(SVG.regex.dots, ' .')
-}
-
-// creates deep clone of array
-function array_clone(arr){
- var clone = arr.slice(0)
- for(var i = clone.length; i--;){
- if(Array.isArray(clone[i])){
- clone[i] = array_clone(clone[i])
- }
- }
- return clone
-}
-
-// tests if a given element is instance of an object
-function is(el, obj){
- return el instanceof obj
-}
-
-// tests if a given selector matches an element
-function matches(el, selector) {
- return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);
-}
-
-// Convert dash-separated-string to camelCase
-function camelCase(s) {
- return s.toLowerCase().replace(/-(.)/g, function(m, g) {
- return g.toUpperCase()
- })
-}
-
-// Capitalize first letter of a string
-function capitalize(s) {
- return s.charAt(0).toUpperCase() + s.slice(1)
-}
-
-// Ensure to six-based hex
-function fullHex(hex) {
- return hex.length == 4 ?
- [ '#',
- hex.substring(1, 2), hex.substring(1, 2)
- , hex.substring(2, 3), hex.substring(2, 3)
- , hex.substring(3, 4), hex.substring(3, 4)
- ].join('') : hex
-}
-
-// Component to hex value
-function compToHex(comp) {
- var hex = comp.toString(16)
- return hex.length == 1 ? '0' + hex : hex
-}
-
-// Calculate proportional width and height values when necessary
-function proportionalSize(element, width, height) {
- if (width == null || height == null) {
- var box = element.bbox()
-
- if (width == null)
- width = box.width / box.height * height
- else if (height == null)
- height = box.height / box.width * width
- }
-
- return {
- width: width
- , height: height
- }
-}
-
-// Delta transform point
-function deltaTransformPoint(matrix, x, y) {
- return {
- x: x * matrix.a + y * matrix.c + 0
- , y: x * matrix.b + y * matrix.d + 0
- }
-}
-
-// Map matrix array to object
-function arrayToMatrix(a) {
- return { a: a[0], b: a[1], c: a[2], d: a[3], e: a[4], f: a[5] }
-}
-
-// Parse matrix if required
-function parseMatrix(matrix) {
- if (!(matrix instanceof SVG.Matrix))
- matrix = new SVG.Matrix(matrix)
-
- return matrix
-}
-
-// Add centre point to transform object
-function ensureCentre(o, target) {
- o.cx = o.cx == null ? target.bbox().cx : o.cx
- o.cy = o.cy == null ? target.bbox().cy : o.cy
-}
-
-// PathArray Helpers
-function arrayToString(a) {
- for (var i = 0, il = a.length, s = ''; i < il; i++) {
- s += a[i][0]
-
- if (a[i][1] != null) {
- s += a[i][1]
-
- if (a[i][2] != null) {
- s += ' '
- s += a[i][2]
-
- if (a[i][3] != null) {
- s += ' '
- s += a[i][3]
- s += ' '
- s += a[i][4]
-
- if (a[i][5] != null) {
- s += ' '
- s += a[i][5]
- s += ' '
- s += a[i][6]
-
- if (a[i][7] != null) {
- s += ' '
- s += a[i][7]
- }
- }
- }
- }
- }
- }
-
- return s + ' '
-}
-
-// Deep new id assignment
-function assignNewId(node) {
- // do the same for SVG child nodes as well
- for (var i = node.children.length - 1; i >= 0; i--)
- assignNewId(node.children[i])
-
- if(node.id)
- return SVG.adopt(node).id(SVG.eid(node.nodeName))
-
- return SVG.adopt(node)
-}
-
-// Add more bounding box properties
-function fullBox(b) {
- if (b.x == null) {
- b.x = 0
- b.y = 0
- b.width = 0
- b.height = 0
- }
-
- b.w = b.width
- b.h = b.height
- b.x2 = b.x + b.width
- b.y2 = b.y + b.height
- b.cx = b.x + b.width / 2
- b.cy = b.y + b.height / 2
-
- return b
-}
-
-// Get id from reference string
-function idFromReference(url) {
- var m = (url || '').toString().match(SVG.regex.reference)
-
- if (m) return m[1]
-}
-
-// Create matrix array for looping
-var abcdef = 'abcdef'.split('')
-
-SVG.Box = SVG.invent({
- create: function(source) {
- var base = [0,0,0,0]
- source = typeof source === 'string' ?
- source.split(SVG.regex.delimiter).map(parseFloat) :
- Array.isArray(source) ?
- source :
- typeof source == 'object' ?
- [source.left != null ? source.left : source.x, source.top != null ? source.top : source.y, source.width, source.height] :
- arguments.length == 4 ?
- [].slice.call(arguments) :
- base
-
- this.x = source[0]
- this.y = source[1]
- this.width = source[2]
- this.height = source[3]
-
- // add center, right, bottom...
- fullBox(this)
- }
-, extend: {
- // Merge rect box with another, return a new instance
- merge: function(box) {
- var x = Math.min(this.x, box.x)
- , y = Math.min(this.y, box.y)
-
- return new SVG.Box(
- x, y,
- Math.max(this.x + this.width, box.x + box.width) - x,
- Math.max(this.y + this.height, box.y + box.height) - y
- )
- }
-
- , transform: function(m) {
- var xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, p, bbox
-
- var pts = [
- new SVG.Point(this.x, this.y),
- new SVG.Point(this.x2, this.y),
- new SVG.Point(this.x, this.y2),
- new SVG.Point(this.x2, this.y2)
- ]
-
- pts.forEach(function(p) {
- p = p.transform(m)
- xMin = Math.min(xMin,p.x)
- xMax = Math.max(xMax,p.x)
- yMin = Math.min(yMin,p.y)
- yMax = Math.max(yMax,p.y)
- })
-
- return new SVG.Box(
- xMin, yMin,
- xMax-xMin,
- yMax-yMin
- )
- }
-
- , addOffset: function() {
- // offset by window scroll position, because getBoundingClientRect changes when window is scrolled
- this.x += window.pageXOffset
- this.y += window.pageYOffset
- return this
- }
- , toString: function() {
- return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height
- }
- , morph: function(x, y, width, height){
- this.destination = new SVG.Box(x, y, width, height)
- return this
- }
-
- , at: function(pos) {
- if(!this.destination) return this
-
- return new SVG.Box(
- this.x + (this.destination.x - this.x) * pos
- , this.y + (this.destination.y - this.y) * pos
- , this.width + (this.destination.width - this.width) * pos
- , this.height + (this.destination.height - this.height) * pos
- )
-
- }
- }
-
- // Define Parent
-, parent: SVG.Element
-
- // Constructor
-, construct: {
- // Get bounding box
- bbox: function() {
- var box
-
- try {
- // find native bbox
- box = this.node.getBBox()
-
- if(isNulledBox(box) && !domContains(this.node)) {
- throw new Exception('Element not in the dom')
- }
- } catch(e) {
- try {
- var clone = this.clone(SVG.parser().svg).show()
- box = clone.node.getBBox()
- clone.remove()
- } catch(e) {
- console.warn('Getting a bounding box of this element is not possible')
- }
- }
-
- return new SVG.Box(box)
- }
-
- , rbox: function(el) {
- // IE11 throws an error when element not in dom
- try{
- var box = new SVG.Box(this.node.getBoundingClientRect())
- if (el) return box.transform(el.screenCTM().inverse())
- return box.addOffset()
- } catch(e) {
- return new SVG.Box()
- }
- }
- }
-})
-
-SVG.extend([SVG.Doc, SVG.Nested, SVG.Symbol, SVG.Image, SVG.Pattern, SVG.Marker, SVG.ForeignObject, SVG.View], {
- viewbox: function(x, y, width, height) {
- // act as getter
- if(x == null) return new SVG.Box(this.attr('viewBox'))
-
- // act as setter
- return this.attr('viewBox', new SVG.Box(x, y, width, height))
- }
-})
-
-SVG.parser = function() {
- var b
-
- if(!SVG.parser.nodes.svg.node.parentNode) {
- b = document.body || document.documentElement
- SVG.parser.nodes.svg.addTo(b)
- }
-
- return SVG.parser.nodes
-}
-
-SVG.parser.nodes = {
- svg: new SVG.Nested().size(2, 0).css({
- opacity:0,
- position:'absolute',
- left:'-100%',
- top:'-100%',
- overflow:'hidden'
- })
-}
-
-SVG.parser.nodes.path = SVG.parser.nodes.svg.path().node
-
-
-return SVG
-
-})); \ No newline at end of file
+
+SVG.Transformation = SVG.invent({
+
+ create: function (source, inversed) {
+ if (arguments.length > 1 && typeof inversed !== 'boolean') {
+ return this.constructor.bind(this)([].slice.call(arguments))
+ }
+
+ var i, len
+ if (Array.isArray(source)) {
+ for (i = 0, len = this.arguments.length; i < len; ++i) {
+ this[this.arguments[i]] = source[i]
+ }
+ } else if (typeof source === 'object') {
+ for (i = 0, len = this.arguments.length; i < len; ++i) {
+ this[this.arguments[i]] = source[this.arguments[i]]
+ }
+ }
+
+ this.inversed = false
+
+ if (inversed === true) {
+ this.inversed = true
+ }
+ },
+
+ extend: {
+
+ arguments: [],
+ method: '',
+
+ at: function (pos) {
+ var params = []
+
+ for (var i = 0, len = this.arguments.length; i < len; ++i) {
+ params.push(this[this.arguments[i]])
+ }
+
+ var m = this._undo || new SVG.Matrix()
+
+ m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos)
+
+ return this.inversed ? m.inverse() : m
+ },
+
+ undo: function (o) {
+ for (var i = 0, len = this.arguments.length; i < len; ++i) {
+ o[this.arguments[i]] = typeof this[this.arguments[i]] === 'undefined' ? 0 : o[this.arguments[i]]
+ }
+
+ // The method SVG.Matrix.extract which was used before calling this
+ // method to obtain a value for the parameter o doesn't return a cx and
+ // a cy so we use the ones that were provided to this object at its creation
+ o.cx = this.cx
+ o.cy = this.cy
+
+ this._undo = new SVG[capitalize(this.method)](o, true).at(1)
+ return this
+ }
+
+ }
+
+})
+
+SVG.Translate = SVG.invent({
+
+ parent: SVG.Matrix,
+ inherit: SVG.Transformation,
+
+ create: function (source, inversed) {
+ this.constructor.apply(this, [].slice.call(arguments))
+ },
+
+ extend: {
+ arguments: ['transformedX', 'transformedY'],
+ method: 'translate'
+ }
+
+})
+
+SVG.Rotate = SVG.invent({
+
+ parent: SVG.Matrix,
+ inherit: SVG.Transformation,
+
+ create: function (source, inversed) {
+ this.constructor.apply(this, [].slice.call(arguments))
+ },
+
+ extend: {
+ arguments: ['rotation', 'cx', 'cy'],
+ method: 'rotate',
+ at: function (pos) {
+ var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy)
+ return this.inversed ? m.inverse() : m
+ },
+ undo: function (o) {
+ this._undo = o
+ return this
+ }
+ }
+
+})
+
+SVG.Scale = SVG.invent({
+
+ parent: SVG.Matrix,
+ inherit: SVG.Transformation,
+
+ create: function (source, inversed) {
+ this.constructor.apply(this, [].slice.call(arguments))
+ },
+
+ extend: {
+ arguments: ['scaleX', 'scaleY', 'cx', 'cy'],
+ method: 'scale'
+ }
+
+})
+
+SVG.Skew = SVG.invent({
+
+ parent: SVG.Matrix,
+ inherit: SVG.Transformation,
+
+ create: function (source, inversed) {
+ this.constructor.apply(this, [].slice.call(arguments))
+ },
+
+ extend: {
+ arguments: ['skewX', 'skewY', 'cx', 'cy'],
+ method: 'skew'
+ }
+})
+
+/* global camelCase */
+
+SVG.extend(SVG.Element, {
+ // Dynamic style generator
+ css: function (s, v) {
+ var ret = {}
+ var t, i
+ if (arguments.length === 0) {
+ // get full style as object
+ this.node.style.cssText.split(/\s*;\s*/).filter(function (el) { return !!el.length }).forEach(function (el) {
+ t = el.split(/\s*:\s*/)
+ ret[t[0]] = t[1]
+ })
+ return ret
+ }
+
+ if (arguments.length < 2) {
+ // get style properties in the array
+ if (Array.isArray(s)) {
+ for (i = s.length; i--;) {
+ ret[camelCase(s[i])] = this.node.style[camelCase(s[i])]
+ }
+ return ret
+ }
+
+ // get style for property
+ if (typeof s === 'string') {
+ return this.node.style[camelCase(s)]
+ }
+
+ // set styles in object
+ if (typeof s === 'object') {
+ for (i in s) {
+ // set empty string if null/undefined/'' was given
+ this.node.style[camelCase(i)] = (s[i] == null || SVG.regex.isBlank.test(s[i])) ? '' : s[i]
+ }
+ }
+ }
+
+ // set style for property
+ if (arguments.length === 2) {
+ this.node.style[camelCase(s)] = (v == null || SVG.regex.isBlank.test(v)) ? '' : v
+ }
+
+ return this
+ }
+})
+
+/* global createElement */
+
+SVG.Parent = SVG.invent({
+ // Initialize node
+ create: function (node) {
+ this.constructor(node)
+ },
+
+ // Inherit from
+ inherit: SVG.Element,
+
+ // Add class methods
+ extend: {
+ // Returns all child elements
+ children: function () {
+ return SVG.utils.map(this.node.children, function (node) {
+ return SVG.adopt(node)
+ })
+ },
+ // Add given element at a position
+ add: function (element, i) {
+ element = createElement(element)
+
+ if (i == null) {
+ this.node.appendChild(element.node)
+ } else if (element.node !== this.node.children[i]) {
+ this.node.insertBefore(element.node, this.node.children[i])
+ }
+
+ return this
+ },
+ // Basically does the same as `add()` but returns the added element instead
+ put: function (element, i) {
+ this.add(element, i)
+ return element.instance || 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 [].slice.call(this.node.children).indexOf(element.node)
+ },
+ // Get a element at the given index
+ get: function (i) {
+ return SVG.adopt(this.node.children[i])
+ },
+ // Get first child
+ first: function () {
+ return this.get(0)
+ },
+ // Get the last child
+ last: function () {
+ return this.get(this.node.children.length - 1)
+ },
+ // Iterates over all children and invokes a given block
+ each: function (block, deep) {
+ var children = this.children()
+ var i, il
+
+ 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.Parent)) {
+ children[i].each(block, deep)
+ }
+ }
+
+ return this
+ },
+ // Remove a given child
+ removeElement: function (element) {
+ this.node.removeChild(element.node)
+
+ return this
+ },
+ // Remove all elements in this container
+ clear: function () {
+ // remove children
+ while (this.node.hasChildNodes()) {
+ this.node.removeChild(this.node.lastChild)
+ }
+
+ // remove defs reference
+ delete this._defs
+
+ return this
+ }
+ }
+
+})
+
+SVG.extend(SVG.Parent, {
+ flatten: function (parent) {
+ if (this instanceof SVG.Defs) return this
+
+ parent = parent || (this instanceof SVG.Doc ? this : this.parent(SVG.Parent))
+
+ this.each(function () {
+ if (this instanceof SVG.Defs) return this
+ if (this instanceof SVG.Parent) return this.flatten(parent)
+ return this.toParent(parent)
+ })
+
+ // we need this so that SVG.Doc does not get removed
+ this.node.firstElementChild || this.remove()
+
+ return this
+ }
+})
+
+SVG.Container = SVG.invent({
+ // Initialize node
+ create: function (node) {
+ this.constructor(node)
+ },
+
+ // Inherit from
+ inherit: SVG.Parent
+})
+
+// Add events to elements
+;[ 'click',
+ 'dblclick',
+ 'mousedown',
+ 'mouseup',
+ 'mouseover',
+ 'mouseout',
+ 'mousemove',
+ // , 'mouseenter' -> not supported by IE
+ // , 'mouseleave' -> not supported by IE
+ 'touchstart',
+ 'touchmove',
+ 'touchleave',
+ 'touchend',
+ 'touchcancel' ].forEach(function (event) {
+ // add event to SVG.Element
+ SVG.Element.prototype[event] = function (f) {
+ // bind event to element rather than element node
+ SVG.on(this, event, f)
+ return this
+ }
+ })
+
+// Initialize listeners stack
+SVG.listeners = []
+SVG.handlerMap = []
+SVG.listenerId = 0
+
+// Add event binder in the SVG namespace
+SVG.on = function (node, events, listener, binding, options) {
+ events.split(SVG.regex.delimiter).forEach(function (event) {
+ // create listener, get object-index
+ var l = listener.bind(binding || node)
+ var n = node instanceof SVG.Element ? node.node : node
+ var index = (SVG.handlerMap.indexOf(n) + 1 || SVG.handlerMap.push(n)) - 1
+ var ev = event.split('.')[0]
+ var ns = event.split('.')[1] || '*'
+
+ // ensure valid object
+ SVG.listeners[index] = SVG.listeners[index] || {}
+ SVG.listeners[index][ev] = SVG.listeners[index][ev] || {}
+ SVG.listeners[index][ev][ns] = SVG.listeners[index][ev][ns] || {}
+
+ if (!listener._svgjsListenerId) {
+ listener._svgjsListenerId = ++SVG.listenerId
+ }
+
+ // reference listener
+ SVG.listeners[index][ev][ns][listener._svgjsListenerId] = l
+
+ // add listener
+ n.addEventListener(ev, l, options || false)
+ })
+}
+
+// Add event unbinder in the SVG namespace
+SVG.off = function (node, event, listener) {
+ var index = SVG.handlerMap.indexOf(node)
+ var ev = event && event.split('.')[0]
+ var ns = event && event.split('.')[1]
+ var namespace = ''
+
+ if (index === -1) return
+
+ if (listener) {
+ if (typeof listener === 'function') listener = listener._svgjsListenerId
+ if (!listener) return
+
+ // remove listener reference
+ if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns || '*']) {
+ // remove listener
+ node.removeEventListener(ev, SVG.listeners[index][ev][ns || '*'][listener], false)
+
+ delete SVG.listeners[index][ev][ns || '*'][listener]
+ }
+ } else if (ns && ev) {
+ // remove all listeners for a namespaced event
+ if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns]) {
+ for (listener in SVG.listeners[index][ev][ns]) {
+ SVG.off(node, [ev, ns].join('.'), listener)
+ }
+
+ delete SVG.listeners[index][ev][ns]
+ }
+ } else if (ns) {
+ // remove all listeners for a specific namespace
+ for (event in SVG.listeners[index]) {
+ for (namespace in SVG.listeners[index][event]) {
+ if (ns === namespace) {
+ SVG.off(node, [event, ns].join('.'))
+ }
+ }
+ }
+ } else if (ev) {
+ // remove all listeners for the event
+ if (SVG.listeners[index][ev]) {
+ for (namespace in SVG.listeners[index][ev]) {
+ SVG.off(node, [ev, namespace].join('.'))
+ }
+
+ delete SVG.listeners[index][ev]
+ }
+ } else {
+ // remove all listeners on a given node
+ for (event in SVG.listeners[index]) {
+ SVG.off(node, event)
+ }
+
+ delete SVG.listeners[index]
+ delete SVG.handlerMap[index]
+ }
+}
+
+//
+SVG.extend(SVG.Element, {
+ // Bind given event to listener
+ on: function (event, listener, binding, options) {
+ SVG.on(this, event, listener, binding, options)
+ return this
+ },
+
+ // Unbind event from listener
+ off: function (event, listener) {
+ SVG.off(this.node, event, listener)
+ return this
+ },
+
+ // Fire given event
+ fire: function (event, data) {
+ // Dispatch event
+ if (event instanceof window.Event) {
+ this.node.dispatchEvent(event)
+ } else {
+ this.node.dispatchEvent(event = new window.CustomEvent(event, {detail: data, cancelable: true}))
+ }
+
+ this._event = event
+ return this
+ },
+
+ event: function () {
+ return this._event
+ }
+})
+
+SVG.Defs = SVG.invent({
+ // Initialize node
+ create: 'defs',
+
+ // Inherit from
+ inherit: SVG.Container
+})
+
+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.transform('x') : this.transform({ x: x - this.x() }, true)
+ },
+ // Move over y-axis
+ y: function (y) {
+ return y == null ? this.transform('y') : this.transform({ y: y - this.y() }, true)
+ },
+ // Move by center over x-axis
+ cx: function (x) {
+ return x == null ? this.gbox().cx : this.x(x - this.gbox().width / 2)
+ },
+ // Move by center over y-axis
+ cy: function (y) {
+ return y == null ? this.gbox().cy : this.y(y - this.gbox().height / 2)
+ },
+ gbox: function () {
+ var bbox = this.bbox()
+ var trans = this.transform()
+
+ bbox.x += trans.x
+ bbox.x2 += trans.x
+ bbox.cx += trans.x
+
+ bbox.y += trans.y
+ bbox.y2 += trans.y
+ bbox.cy += trans.y
+
+ return bbox
+ }
+ },
+
+ // Add parent method
+ construct: {
+ // Create a group element
+ group: function () {
+ return this.put(new SVG.G())
+ }
+ }
+})
+
+// ### This module adds backward / forward functionality to elements.
+
+//
+SVG.extend(SVG.Element, {
+ // Get all siblings, including myself
+ siblings: function () {
+ return this.parent().children()
+ },
+
+ // Get the curent position siblings
+ position: function () {
+ return this.parent().index(this)
+ },
+
+ // Get the next element (will return null if there is none)
+ next: function () {
+ return this.siblings()[this.position() + 1]
+ },
+
+ // Get the next element (will return null if there is none)
+ prev: function () {
+ return this.siblings()[this.position() - 1]
+ },
+
+ // Send given element one step forward
+ forward: function () {
+ var i = this.position() + 1
+ var p = this.parent()
+
+ // move node one step forward
+ p.removeElement(this).add(this, i)
+
+ // make sure defs node is always at the top
+ if (p instanceof SVG.Doc) {
+ p.node.appendChild(p.defs().node)
+ }
+
+ return this
+ },
+
+ // Send given element one step backward
+ backward: function () {
+ var i = this.position()
+
+ if (i > 0) {
+ this.parent().removeElement(this).add(this, i - 1)
+ }
+
+ return this
+ },
+
+ // Send given element all the way to the front
+ front: function () {
+ var p = this.parent()
+
+ // Move node forward
+ p.node.appendChild(this.node)
+
+ // Make sure defs node is always at the top
+ if (p instanceof SVG.Doc) {
+ p.node.appendChild(p.defs().node)
+ }
+
+ return this
+ },
+
+ // Send given element all the way to the back
+ back: function () {
+ if (this.position() > 0) {
+ this.parent().removeElement(this).add(this, 0)
+ }
+
+ return this
+ },
+
+ // Inserts a given element before the targeted element
+ before: function (element) {
+ element.remove()
+
+ var i = this.position()
+
+ this.parent().add(element, i)
+
+ return this
+ },
+
+ // Insters a given element after the targeted element
+ after: function (element) {
+ element.remove()
+
+ var i = this.position()
+
+ this.parent().add(element, i + 1)
+
+ return this
+ }
+})
+
+SVG.Mask = SVG.invent({
+ // Initialize node
+ create: 'mask',
+
+ // Inherit from
+ inherit: SVG.Container,
+
+ // Add class methods
+ extend: {
+ // Unmask all masked elements and remove itself
+ remove: function () {
+ // unmask all targets
+ this.targets().forEach(function (el) {
+ el.unmask()
+ })
+
+ // remove mask from parent
+ return SVG.Element.prototype.remove.call(this)
+ },
+
+ targets: function () {
+ return SVG.select('svg [mask*="' + this.id() + '"]')
+ }
+ },
+
+ // 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) {
+ // use given mask or create a new one
+ var masker = element instanceof SVG.Mask ? element : this.parent().mask().add(element)
+
+ // apply mask
+ return this.attr('mask', 'url("#' + masker.id() + '")')
+ },
+ // Unmask element
+ unmask: function () {
+ return this.attr('mask', null)
+ },
+ masker: function () {
+ return this.reference('mask')
+ }
+})
+
+SVG.ClipPath = SVG.invent({
+ // Initialize node
+ create: 'clipPath',
+
+ // Inherit from
+ inherit: SVG.Container,
+
+ // Add class methods
+ extend: {
+ // Unclip all clipped elements and remove itself
+ remove: function () {
+ // unclip all targets
+ this.targets().forEach(function (el) {
+ el.unclip()
+ })
+
+ // remove clipPath from parent
+ return SVG.Element.prototype.remove.call(this)
+ },
+
+ targets: function () {
+ return SVG.select('svg [clip-path*="' + this.id() + '"]')
+ }
+ },
+
+ // Add parent method
+ construct: {
+ // Create clipping element
+ clip: function () {
+ return this.defs().put(new SVG.ClipPath())
+ }
+ }
+})
+
+//
+SVG.extend(SVG.Element, {
+ // Distribute clipPath to svg element
+ clipWith: function (element) {
+ // use given clip or create a new one
+ var clipper = element instanceof SVG.ClipPath ? element : this.parent().clip().add(element)
+
+ // apply mask
+ return this.attr('clip-path', 'url("#' + clipper.id() + '")')
+ },
+ // Unclip element
+ unclip: function () {
+ return this.attr('clip-path', null)
+ },
+ clipper: function () {
+ return this.reference('clip-path')
+ }
+
+})
+
+SVG.Gradient = SVG.invent({
+ // Initialize node
+ create: function (type) {
+ this.constructor(typeof type === 'object' ? type : SVG.create(type + 'Gradient'))
+ },
+
+ // Inherit from
+ inherit: SVG.Container,
+
+ // Add class methods
+ extend: {
+ // Add a color stop
+ stop: function (offset, color, opacity) {
+ return this.put(new SVG.Stop()).update(offset, color, opacity)
+ },
+ // Update gradient
+ update: function (block) {
+ // remove all stops
+ this.clear()
+
+ // invoke passed block
+ if (typeof block === 'function') {
+ block.call(this, this)
+ }
+
+ return this
+ },
+ // Return the fill id
+ url: function () {
+ return 'url(#' + this.id() + ')'
+ },
+ // Alias string convertion to fill
+ toString: function () {
+ return this.url()
+ },
+ // custom attr to handle transform
+ attr: function (a, b, c) {
+ if (a === 'transform') a = 'gradientTransform'
+ return SVG.Container.prototype.attr.call(this, a, b, c)
+ }
+ },
+
+ // Add parent method
+ construct: {
+ // Create gradient element in defs
+ gradient: function (type, block) {
+ return this.defs().gradient(type, block)
+ }
+ }
+})
+
+// Add animatable methods to both gradient and fx module
+SVG.extend([SVG.Gradient, SVG.FX], {
+ // From position
+ from: function (x, y) {
+ return (this._target || this).type === 'radialGradient'
+ ? 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._target || this).type === 'radialGradient'
+ ? this.attr({ cx: new SVG.Number(x), cy: new SVG.Number(y) })
+ : this.attr({ x2: new SVG.Number(x), y2: new SVG.Number(y) })
+ }
+})
+
+// Base gradient generation
+SVG.extend(SVG.Defs, {
+ // define gradient
+ gradient: function (type, block) {
+ return this.put(new SVG.Gradient(type)).update(block)
+ }
+
+})
+
+SVG.Stop = SVG.invent({
+ // Initialize node
+ create: 'stop',
+
+ // Inherit from
+ inherit: SVG.Element,
+
+ // Add class methods
+ extend: {
+ // add color stops
+ update: function (o) {
+ if (typeof o === 'number' || o instanceof SVG.Number) {
+ o = {
+ offset: arguments[0],
+ color: arguments[1],
+ opacity: arguments[2]
+ }
+ }
+
+ // 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
+ }
+ }
+
+})
+
+SVG.Pattern = SVG.invent({
+ // Initialize node
+ create: 'pattern',
+
+ // Inherit from
+ inherit: SVG.Container,
+
+ // Add class methods
+ extend: {
+ // Return the fill id
+ url: function () {
+ return 'url(#' + this.id() + ')'
+ },
+ // Update pattern by rebuilding
+ update: function (block) {
+ // remove content
+ this.clear()
+
+ // invoke passed block
+ if (typeof block === 'function') {
+ block.call(this, this)
+ }
+
+ return this
+ },
+ // Alias string convertion to fill
+ toString: function () {
+ return this.url()
+ },
+ // custom attr to handle transform
+ attr: function (a, b, c) {
+ if (a === 'transform') a = 'patternTransform'
+ return SVG.Container.prototype.attr.call(this, a, b, c)
+ }
+
+ },
+
+ // Add parent method
+ construct: {
+ // Create pattern element in defs
+ pattern: function (width, height, block) {
+ return this.defs().pattern(width, height, block)
+ }
+ }
+})
+
+SVG.extend(SVG.Defs, {
+ // Define gradient
+ pattern: function (width, height, block) {
+ return this.put(new SVG.Pattern()).update(block).attr({
+ x: 0,
+ y: 0,
+ width: width,
+ height: height,
+ patternUnits: 'userSpaceOnUse'
+ })
+ }
+
+})
+
+SVG.Doc = SVG.invent({
+ // Initialize node
+ create: function (node) {
+ this.constructor(node || SVG.create('svg'))
+
+ // set svg element attributes and ensure defs node
+ this.namespace().defs()
+ },
+
+ // Inherit from
+ inherit: SVG.Container,
+
+ // Add class methods
+ extend: {
+ // Add namespaces
+ namespace: function () {
+ return this
+ .attr({ xmlns: SVG.ns, version: '1.1' })
+ .attr('xmlns:xlink', SVG.xlink, SVG.xmlns)
+ .attr('xmlns:svgjs', SVG.svgjs, SVG.xmlns)
+ },
+ // Creates and returns defs element
+ defs: function () {
+ return SVG.adopt(this.node.getElementsByTagName('defs')[0]) || this.put(new SVG.Defs())
+ },
+ // custom parent method
+ parent: function () {
+ return this.node.parentNode.nodeName === '#document' ? null : this.node.parentNode
+ },
+ // Removes the doc from the DOM
+ remove: function () {
+ if (this.parent()) {
+ this.parent().removeChild(this.node)
+ }
+
+ return this
+ },
+ clear: function () {
+ // remove children
+ while (this.node.hasChildNodes()) {
+ this.node.removeChild(this.node.lastChild)
+ }
+ return this
+ },
+ toNested: function () {
+ var el = SVG.create('svg')
+ this.node.instance = null
+ el.appendChild(this.node)
+
+ return SVG.adopt(this.node)
+ }
+ }
+
+})
+
+
+SVG.Shape = SVG.invent({
+ // Initialize node
+ create: function (node) {
+ this.constructor(node)
+ },
+
+ // Inherit from
+ inherit: SVG.Element
+})
+
+
+SVG.Bare = SVG.invent({
+ // Initialize
+ create: function (element, inherit) {
+ // construct element
+ this.constructor(SVG.create(element))
+
+ // inherit custom methods
+ if (inherit) {
+ for (var method in inherit.prototype) {
+ if (typeof inherit.prototype[method] === 'function') {
+ this[method] = inherit.prototype[method]
+ }
+ }
+ }
+ },
+
+ // Inherit from
+ inherit: SVG.Element,
+
+ // Add methods
+ extend: {
+ // Insert some plain text
+ words: function (text) {
+ // remove contents
+ while (this.node.hasChildNodes()) {
+ this.node.removeChild(this.node.lastChild)
+ }
+
+ // create text node
+ this.node.appendChild(document.createTextNode(text))
+
+ return this
+ }
+ }
+})
+
+SVG.extend(SVG.Parent, {
+ // Create an element that is not described by SVG.js
+ element: function (element, inherit) {
+ return this.put(new SVG.Bare(element, inherit))
+ }
+})
+
+
+SVG.Symbol = SVG.invent({
+ // Initialize node
+ create: 'symbol',
+
+ // Inherit from
+ inherit: SVG.Container,
+
+ construct: {
+ // create symbol
+ symbol: function () {
+ return this.put(new SVG.Symbol())
+ }
+ }
+})
+
+
+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, file) {
+ // Set lined element
+ return this.attr('href', (file || '') + '#' + element, SVG.xlink)
+ }
+ },
+
+ // Add parent method
+ construct: {
+ // Create a use element
+ use: function (element, file) {
+ return this.put(new SVG.Use()).element(element, file)
+ }
+ }
+})
+
+
+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)
+ }
+ }
+})
+
+/* global proportionalSize */
+
+SVG.Circle = SVG.invent({
+ // Initialize node
+ create: 'circle',
+
+ // Inherit from
+ inherit: SVG.Shape,
+
+ // Add parent method
+ construct: {
+ // Create circle element, based on ellipse
+ circle: function (size) {
+ return this.put(new SVG.Circle()).rx(new SVG.Number(size).divide(2)).move(0, 0)
+ }
+ }
+})
+
+SVG.extend([SVG.Circle, SVG.FX], {
+ // Radius x value
+ rx: function (rx) {
+ return this.attr('r', rx)
+ },
+ // Alias radius x value
+ ry: function (ry) {
+ return this.rx(ry)
+ }
+})
+
+SVG.Ellipse = SVG.invent({
+ // Initialize node
+ create: 'ellipse',
+
+ // Inherit from
+ inherit: SVG.Shape,
+
+ // Add parent method
+ construct: {
+ // Create an ellipse
+ ellipse: function (width, height) {
+ return this.put(new SVG.Ellipse()).size(width, height).move(0, 0)
+ }
+ }
+})
+
+SVG.extend([SVG.Ellipse, SVG.Rect, SVG.FX], {
+ // Radius x value
+ rx: function (rx) {
+ return this.attr('rx', rx)
+ },
+ // Radius y value
+ ry: function (ry) {
+ return this.attr('ry', ry)
+ }
+})
+
+// Add common method
+SVG.extend([SVG.Circle, SVG.Ellipse], {
+ // Move over x-axis
+ x: function (x) {
+ return x == null ? this.cx() - this.rx() : this.cx(x + this.rx())
+ },
+ // Move over y-axis
+ y: function (y) {
+ return y == null ? this.cy() - this.ry() : this.cy(y + this.ry())
+ },
+ // Move by center over x-axis
+ cx: function (x) {
+ return x == null ? this.attr('cx') : this.attr('cx', x)
+ },
+ // Move by center over y-axis
+ cy: function (y) {
+ return y == null ? this.attr('cy') : this.attr('cy', y)
+ },
+ // Set width of element
+ width: function (width) {
+ return width == null ? this.rx() * 2 : this.rx(new SVG.Number(width).divide(2))
+ },
+ // Set height of element
+ height: function (height) {
+ return height == null ? this.ry() * 2 : this.ry(new SVG.Number(height).divide(2))
+ },
+ // Custom size function
+ size: function (width, height) {
+ var p = proportionalSize(this, width, height)
+
+ return this
+ .rx(new SVG.Number(p.width).divide(2))
+ .ry(new SVG.Number(p.height).divide(2))
+ }
+})
+
+/* global proportionalSize */
+
+SVG.Line = SVG.invent({
+ // Initialize node
+ create: 'line',
+
+ // Inherit from
+ inherit: SVG.Shape,
+
+ // Add class methods
+ extend: {
+ // Get array
+ array: function () {
+ return new SVG.PointArray([
+ [ this.attr('x1'), this.attr('y1') ],
+ [ this.attr('x2'), this.attr('y2') ]
+ ])
+ },
+ // Overwrite native plot() method
+ plot: function (x1, y1, x2, y2) {
+ if (x1 == null) {
+ return this.array()
+ } else if (typeof y1 !== 'undefined') {
+ x1 = { x1: x1, y1: y1, x2: x2, y2: y2 }
+ } else {
+ x1 = new SVG.PointArray(x1).toLine()
+ }
+
+ return this.attr(x1)
+ },
+ // Move by left top corner
+ move: function (x, y) {
+ return this.attr(this.array().move(x, y).toLine())
+ },
+ // Set element size to given width and height
+ size: function (width, height) {
+ var p = proportionalSize(this, width, height)
+ return this.attr(this.array().size(p.width, p.height).toLine())
+ }
+ },
+
+ // Add parent method
+ construct: {
+ // Create a line element
+ line: function (x1, y1, x2, y2) {
+ // make sure plot is called as a setter
+ // x1 is not necessarily a number, it can also be an array, a string and a SVG.PointArray
+ return SVG.Line.prototype.plot.apply(
+ this.put(new SVG.Line())
+ , x1 != null ? [x1, y1, x2, y2] : [0, 0, 0, 0]
+ )
+ }
+ }
+})
+
+/* global proportionalSize */
+
+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) {
+ // make sure plot is called as a setter
+ return this.put(new SVG.Polyline()).plot(p || new SVG.PointArray())
+ }
+ }
+})
+
+SVG.Polygon = SVG.invent({
+ // Initialize node
+ create: 'polygon',
+
+ // Inherit from
+ inherit: SVG.Shape,
+
+ // Add parent method
+ construct: {
+ // Create a wrapped polygon element
+ polygon: function (p) {
+ // make sure plot is called as a setter
+ return this.put(new SVG.Polygon()).plot(p || new SVG.PointArray())
+ }
+ }
+})
+
+// Add polygon-specific functions
+SVG.extend([SVG.Polyline, SVG.Polygon], {
+ // Get array
+ array: function () {
+ return this._array || (this._array = new SVG.PointArray(this.attr('points')))
+ },
+
+ // Plot new path
+ plot: function (p) {
+ return (p == null) ? this.array()
+ : this.clear().attr('points', typeof p === 'string' ? p
+ : (this._array = new SVG.PointArray(p)))
+ },
+
+ // Clear array cache
+ clear: function () {
+ delete this._array
+ return this
+ },
+
+ // Move by left top corner
+ move: function (x, y) {
+ return this.attr('points', this.array().move(x, y))
+ },
+
+ // Set element size to given width and height
+ size: function (width, height) {
+ var p = proportionalSize(this, width, height)
+ return this.attr('points', this.array().size(p.width, p.height))
+ }
+})
+
+// unify all point to point elements
+SVG.extend([SVG.Line, SVG.Polyline, SVG.Polygon], {
+ // Define morphable array
+ MorphArray: SVG.PointArray,
+ // 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 width of element
+ width: function (width) {
+ var b = this.bbox()
+
+ return width == null ? b.width : this.size(width, b.height)
+ },
+ // Set height of element
+ height: function (height) {
+ var b = this.bbox()
+
+ return height == null ? b.height : this.size(b.width, height)
+ }
+})
+
+/* global proportionalSize */
+
+SVG.Path = SVG.invent({
+ // Initialize node
+ create: 'path',
+
+ // Inherit from
+ inherit: SVG.Shape,
+
+ // Add class methods
+ extend: {
+ // Define morphable array
+ MorphArray: SVG.PathArray,
+ // Get array
+ array: function () {
+ return this._array || (this._array = new SVG.PathArray(this.attr('d')))
+ },
+ // Plot new path
+ plot: function (d) {
+ return (d == null) ? this.array()
+ : this.clear().attr('d', typeof d === 'string' ? d : (this._array = new SVG.PathArray(d)))
+ },
+ // Clear array cache
+ clear: function () {
+ delete this._array
+ return this
+ },
+ // 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 = proportionalSize(this, 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)
+ }
+ },
+
+ // Add parent method
+ construct: {
+ // Create a wrapped path element
+ path: function (d) {
+ // make sure plot is called as a setter
+ return this.put(new SVG.Path()).plot(d || new SVG.PathArray())
+ }
+ }
+})
+
+SVG.Image = SVG.invent({
+ // Initialize node
+ create: 'image',
+
+ // Inherit from
+ inherit: SVG.Shape,
+
+ // Add class methods
+ extend: {
+ // (re)load image
+ load: function (url, callback) {
+ if (!url) return this
+
+ var img = new window.Image()
+
+ SVG.on(img, 'load', function (e) {
+ var p = this.parent(SVG.Pattern)
+
+ // ensure image size
+ if (this.width() === 0 && this.height() === 0) {
+ this.size(img.width, img.height)
+ }
+
+ if (p instanceof SVG.Pattern) {
+ // ensure pattern size if not set
+ if (p.width() === 0 && p.height() === 0) {
+ p.size(this.width(), this.height())
+ }
+ }
+
+ if (typeof callback === 'function') {
+ callback.call(this, {
+ width: img.width,
+ height: img.height,
+ ratio: img.width / img.height,
+ url: url
+ })
+ }
+ }, this)
+
+ SVG.on(img, 'load error', function () {
+ // dont forget to unbind memory leaking events
+ SVG.off(img)
+ })
+
+ return this.attr('href', (img.src = url), SVG.xlink)
+ }
+ },
+
+ // Add parent method
+ construct: {
+ // create image element, load image and set its size
+ image: function (source, callback) {
+ return this.put(new SVG.Image()).size(0, 0).load(source, callback)
+ }
+ }
+})
+
+SVG.Text = SVG.invent({
+ // Initialize node
+ create: function (node) {
+ this.constructor(node || SVG.create('text'))
+ this.dom.leading = new SVG.Number(1.3) // store leading value for rebuilding
+ this._rebuild = true // enable automatic updating of dy values
+ this._build = false // disable build mode for adding multiple lines
+
+ // set default font
+ this.attr('font-family', SVG.defaults.attrs['font-family'])
+ },
+
+ // Inherit from
+ inherit: SVG.Parent,
+
+ // Add class methods
+ extend: {
+ // Move over x-axis
+ x: function (x) {
+ // act as getter
+ if (x == null) {
+ return this.attr('x')
+ }
+
+ return this.attr('x', x)
+ },
+ // Move over y-axis
+ y: function (y) {
+ var oy = this.attr('y')
+ var o = typeof oy === 'number' ? oy - this.bbox().y : 0
+
+ // act as getter
+ if (y == null) {
+ return typeof oy === 'number' ? oy - o : oy
+ }
+
+ return this.attr('y', typeof y === 'number' ? y + o : y)
+ },
+ // Move center over x-axis
+ cx: function (x) {
+ return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2)
+ },
+ // Move center over y-axis
+ cy: function (y) {
+ return y == null ? this.bbox().cy : this.y(y - this.bbox().height / 2)
+ },
+ // Set the text content
+ text: function (text) {
+ // act as getter
+ if (text === undefined) {
+ var children = this.node.childNodes
+ var firstLine = 0
+ text = ''
+
+ for (var i = 0, len = children.length; i < len; ++i) {
+ // skip textPaths - they are no lines
+ if (children[i].nodeName === 'textPath') {
+ if (i === 0) firstLine = 1
+ continue
+ }
+
+ // add newline if its not the first child and newLined is set to true
+ if (i !== firstLine && children[i].nodeType !== 3 && SVG.adopt(children[i]).dom.newLined === true) {
+ text += '\n'
+ }
+
+ // add content of this node
+ text += children[i].textContent
+ }
+
+ return text
+ }
+
+ // remove existing content
+ this.clear().build(true)
+
+ if (typeof text === 'function') {
+ // call block
+ text.call(this, this)
+ } else {
+ // store text and make sure text is not blank
+ text = text.split('\n')
+
+ // build new lines
+ for (var j = 0, jl = text.length; j < jl; j++) {
+ this.tspan(text[j]).newLine()
+ }
+ }
+
+ // disable build mode and rebuild lines
+ return this.build(false).rebuild()
+ },
+ // Set font size
+ size: function (size) {
+ return this.attr('font-size', size).rebuild()
+ },
+ // Set / get leading
+ leading: function (value) {
+ // act as getter
+ if (value == null) {
+ return this.dom.leading
+ }
+
+ // act as setter
+ this.dom.leading = new SVG.Number(value)
+
+ return this.rebuild()
+ },
+ // Rebuild appearance type
+ rebuild: function (rebuild) {
+ // store new rebuild flag if given
+ if (typeof rebuild === 'boolean') {
+ this._rebuild = rebuild
+ }
+
+ // define position of all lines
+ if (this._rebuild) {
+ var self = this
+ var blankLineOffset = 0
+ var dy = this.dom.leading * new SVG.Number(this.attr('font-size'))
+
+ this.each(function () {
+ if (this.dom.newLined) {
+ this.attr('x', self.attr('x'))
+
+ if (this.text() === '\n') {
+ blankLineOffset += dy
+ } else {
+ this.attr('dy', dy + blankLineOffset)
+ blankLineOffset = 0
+ }
+ }
+ })
+
+ this.fire('rebuild')
+ }
+
+ return this
+ },
+ // Enable / disable build mode
+ build: function (build) {
+ this._build = !!build
+ return this
+ },
+ // overwrite method from parent to set data properly
+ setData: function (o) {
+ this.dom = o
+ this.dom.leading = new SVG.Number(o.leading || 1.3)
+ return this
+ }
+ },
+
+ // Add parent method
+ construct: {
+ // Create text element
+ text: function (text) {
+ return this.put(new SVG.Text()).text(text)
+ },
+ // Create plain text element
+ plain: function (text) {
+ return this.put(new SVG.Text()).plain(text)
+ }
+ }
+
+})
+
+SVG.Tspan = SVG.invent({
+ // Initialize node
+ create: 'tspan',
+
+ // Inherit from
+ inherit: SVG.Parent,
+
+ // Add class methods
+ extend: {
+ // Set text content
+ text: function (text) {
+ if (text == null) return this.node.textContent + (this.dom.newLined ? '\n' : '')
+
+ typeof text === 'function' ? text.call(this, this) : this.plain(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 () {
+ // fetch text parent
+ var t = this.parent(SVG.Text)
+
+ // mark new line
+ this.dom.newLined = true
+
+ // apply new hy¡n
+ return this.dy(t.dom.leading * t.attr('font-size')).attr('x', t.x())
+ }
+ }
+})
+
+SVG.extend([SVG.Text, SVG.Tspan], {
+ // Create plain text node
+ plain: function (text) {
+ // clear if build mode is disabled
+ if (this._build === false) {
+ this.clear()
+ }
+
+ // create text node
+ this.node.appendChild(document.createTextNode(text))
+
+ return this
+ },
+ // Create a tspan
+ tspan: function (text) {
+ var tspan = new SVG.Tspan()
+
+ // clear if build mode is disabled
+ if (!this._build) {
+ this.clear()
+ }
+
+ // add new tspan
+ this.node.appendChild(tspan.node)
+
+ return tspan.text(text)
+ },
+ // FIXME: Does this also work for textpath?
+ // Get length of text element
+ length: function () {
+ return this.node.getComputedTextLength()
+ }
+})
+
+SVG.TextPath = SVG.invent({
+ // Initialize node
+ create: 'textPath',
+
+ // Inherit from
+ inherit: SVG.Text,
+
+ // Define parent class
+ parent: SVG.Parent,
+
+ // Add parent method
+ extend: {
+ MorphArray: SVG.PathArray,
+ // return the array of the path track element
+ array: function () {
+ var track = this.track()
+
+ return track ? track.array() : null
+ },
+ // Plot path if any
+ plot: function (d) {
+ var track = this.track()
+ var pathArray = null
+
+ if (track) {
+ pathArray = track.plot(d)
+ }
+
+ return (d == null) ? pathArray : this
+ },
+ // Get the path element
+ track: function () {
+ return this.reference('href')
+ }
+ },
+ construct: {
+ textPath: function (text, path) {
+ return this.defs().path(path).text(text).addTo(this)
+ }
+ }
+})
+
+SVG.extend([SVG.Text], {
+ // Create path for text to run on
+ path: function (track) {
+ var path = new SVG.TextPath()
+
+ // if d is a path, reuse it
+ if (!(track instanceof SVG.Path)) {
+ // create path element
+ track = this.doc().defs().path(track)
+ }
+
+ // link textPath to path and add content
+ path.attr('href', '#' + track, SVG.xlink)
+
+ // add textPath element as child node and return textPath
+ return this.put(path)
+ },
+ // Todo: make this plural?
+ // Get the textPath children
+ textPath: function () {
+ return this.select('textPath')
+ }
+})
+
+SVG.extend([SVG.Path], {
+ // creates a textPath from this path
+ text: function (text) {
+ if (text instanceof SVG.Text) {
+ var txt = text.text()
+ return text.clear().path(this).text(txt)
+ }
+ return this.parent().put(new SVG.Text()).path(this).text(text)
+ }
+ // TODO: Maybe add `targets` to get all textPaths associated with this path
+})
+
+
+SVG.Nested = SVG.invent({
+ // Initialize node
+ create: 'svg',
+
+ // Inherit from
+ inherit: SVG.Container,
+
+ // Add parent method
+ construct: {
+ // Create nested svg document
+ nested: function () {
+ return this.put(new SVG.Nested())
+ }
+ }
+})
+
+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 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) {
+ var link = new SVG.A()
+
+ if (typeof url === 'function') { url.call(link, link) } else {
+ link.to(url)
+ }
+
+ return this.parent().put(link).put(this)
+ }
+
+})
+
+SVG.Marker = SVG.invent({
+ // Initialize node
+ create: 'marker',
+
+ // Inherit from
+ inherit: SVG.Container,
+
+ // Add class methods
+ extend: {
+ // Set width of element
+ width: function (width) {
+ return this.attr('markerWidth', width)
+ },
+ // Set height of element
+ height: function (height) {
+ return this.attr('markerHeight', height)
+ },
+ // Set marker refX and refY
+ ref: function (x, y) {
+ return this.attr('refX', x).attr('refY', y)
+ },
+ // Update marker
+ update: function (block) {
+ // remove all content
+ this.clear()
+
+ // invoke passed block
+ if (typeof block === 'function') { block.call(this, this) }
+
+ return this
+ },
+ // Return the fill id
+ toString: function () {
+ return 'url(#' + this.id() + ')'
+ }
+ },
+
+ // Add parent method
+ construct: {
+ marker: function (width, height, block) {
+ // Create marker element in defs
+ return this.defs().marker(width, height, block)
+ }
+ }
+
+})
+
+SVG.extend(SVG.Defs, {
+ // Create marker
+ marker: function (width, height, block) {
+ // Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto
+ return this.put(new SVG.Marker())
+ .size(width, height)
+ .ref(width / 2, height / 2)
+ .viewbox(0, 0, width, height)
+ .attr('orient', 'auto')
+ .update(block)
+ }
+
+})
+
+SVG.extend([SVG.Line, SVG.Polyline, SVG.Polygon, SVG.Path], {
+ // Create and attach markers
+ marker: function (marker, width, height, block) {
+ var attr = ['marker']
+
+ // Build attribute name
+ if (marker !== 'all') attr.push(marker)
+ attr = attr.join('-')
+
+ // Set marker attribute
+ marker = arguments[1] instanceof SVG.Marker
+ ? arguments[1]
+ : this.doc().marker(width, height, block)
+
+ return this.attr(attr, marker)
+ }
+})
+
+// Define list of available attributes for stroke and fill
+var sugar = {
+ stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset'],
+ fill: ['color', 'opacity', 'rule'],
+ prefix: function (t, a) {
+ return a === 'color' ? t : t + '-' + a
+ }
+}
+
+// Add sugar for fill and stroke
+;['fill', 'stroke'].forEach(function (m) {
+ var extension = {}
+ var i
+
+ extension[m] = function (o) {
+ if (typeof o === 'undefined') {
+ return this
+ }
+ if (typeof o === 'string' || SVG.Color.isRgb(o) || (o && typeof o.fill === 'function')) {
+ this.attr(m, o)
+ } else {
+ // set all attributes from sugar.fill and sugar.stroke list
+ for (i = sugar[m].length - 1; i >= 0; i--) {
+ if (o[sugar[m][i]] != null) {
+ this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]])
+ }
+ }
+ }
+
+ return this
+ }
+
+ SVG.extend([SVG.Element, SVG.FX], extension)
+})
+
+SVG.extend([SVG.Element, SVG.FX], {
+ // Map rotation to transform
+ rotate: function (d, cx, cy) {
+ return this.transform({ rotation: d, cx: cx, cy: cy })
+ },
+ // Map skew to transform
+ skew: function (x, y, cx, cy) {
+ return arguments.length === 1 || arguments.length === 3
+ ? this.transform({ skew: x, cx: y, cy: cx })
+ : this.transform({ skewX: x, skewY: y, cx: cx, cy: cy })
+ },
+ // Map scale to transform
+ scale: function (x, y, cx, cy) {
+ return arguments.length === 1 || arguments.length === 3
+ ? this.transform({ scale: x, cx: y, cy: cx })
+ : this.transform({ scaleX: x, scaleY: y, cx: cx, cy: cy })
+ },
+ // Map translate to transform
+ translate: function (x, y) {
+ return this.transform({ x: x, y: y })
+ },
+ // Map flip to transform
+ flip: function (a, o) {
+ o = typeof a === 'number' ? a : o
+ return this.transform({ flip: a || 'both', offset: o })
+ },
+ // Map matrix to transform
+ matrix: function (m) {
+ return this.attr('transform', new SVG.Matrix(arguments.length === 6 ? [].slice.call(arguments) : m))
+ },
+ // Opacity
+ opacity: function (value) {
+ return this.attr('opacity', value)
+ },
+ // Relative move over x axis
+ dx: function (x) {
+ return this.x(new SVG.Number(x).plus(this instanceof SVG.FX ? 0 : this.x()), true)
+ },
+ // Relative move over y axis
+ dy: function (y) {
+ return this.y(new SVG.Number(y).plus(this instanceof SVG.FX ? 0 : this.y()), true)
+ },
+ // Relative move over x and y axes
+ dmove: function (x, y) {
+ return this.dx(x).dy(y)
+ }
+})
+
+SVG.extend([SVG.Rect, SVG.Ellipse, SVG.Circle, SVG.Gradient, SVG.FX], {
+ // Add x and y radius
+ radius: function (x, y) {
+ var type = (this._target || this).type
+ return type === 'radialGradient' || type === 'radialGradient'
+ ? this.attr('r', new SVG.Number(x))
+ : this.rx(x).ry(y == null ? x : y)
+ }
+})
+
+SVG.extend(SVG.Path, {
+ // Get path length
+ length: function () {
+ return this.node.getTotalLength()
+ },
+ // Get point at length
+ pointAt: function (length) {
+ return new SVG.Point(this.node.getPointAtLength(length))
+ }
+})
+
+SVG.extend([SVG.Parent, SVG.Text, SVG.Tspan, SVG.FX], {
+ // Set font
+ font: function (a, v) {
+ if (typeof a === 'object') {
+ for (v in a) this.font(v, a[v])
+ }
+
+ return a === 'leading'
+ ? this.leading(v)
+ : a === 'anchor'
+ ? this.attr('text-anchor', v)
+ : a === 'size' || a === 'family' || a === 'weight' || a === 'stretch' || a === 'variant' || a === 'style'
+ ? this.attr('font-' + a, v)
+ : this.attr(a, v)
+ }
+})
+
+
+SVG.extend(SVG.Element, {
+ // Store data values on svg nodes
+ data: function (a, v, r) {
+ if (typeof a === 'object') {
+ for (v in a) {
+ this.data(v, a[v])
+ }
+ } else if (arguments.length < 2) {
+ try {
+ return JSON.parse(this.attr('data-' + a))
+ } catch (e) {
+ return this.attr('data-' + a)
+ }
+ } else {
+ this.attr('data-' + a,
+ v === null ? null
+ : r === true || typeof v === 'string' || typeof v === 'number' ? v
+ : JSON.stringify(v)
+ )
+ }
+
+ return this
+ }
+})
+
+
+SVG.extend(SVG.Element, {
+ // Remember arbitrary data
+ remember: function (k, v) {
+ // remember every item in an object individually
+ if (typeof arguments[0] === 'object') {
+ for (var key in k) {
+ this.remember(key, k[key])
+ }
+ } else if (arguments.length === 1) {
+ // retrieve memory
+ return this.memory()[k]
+ } else {
+ // store memory
+ this.memory()[k] = v
+ }
+
+ return this
+ },
+
+ // Erase a given memory
+ forget: function () {
+ if (arguments.length === 0) {
+ this._memory = {}
+ } else {
+ for (var i = arguments.length - 1; i >= 0; i--) {
+ delete this.memory()[arguments[i]]
+ }
+ }
+ return this
+ },
+
+ // Initialize or return local memory object
+ memory: function () {
+ return this._memory || (this._memory = {})
+ }
+})
+
+/* global idFromReference */
+
+// Method for getting an element by id
+SVG.get = function (id) {
+ var node = document.getElementById(idFromReference(id) || id)
+ return SVG.adopt(node)
+}
+
+// Select elements by query string
+SVG.select = function (query, parent) {
+ return SVG.utils.map((parent || document).querySelectorAll(query), function (node) {
+ return SVG.adopt(node)
+ })
+}
+
+SVG.$$ = function (query, parent) {
+ return SVG.utils.map((parent || document).querySelectorAll(query), function (node) {
+ return SVG.adopt(node)
+ })
+}
+
+SVG.$ = function (query, parent) {
+ return SVG.adopt((parent || document).querySelector(query))
+}
+
+SVG.extend(SVG.Parent, {
+ // Scoped select method
+ select: function (query) {
+ return SVG.select(query, this.node)
+ }
+})
+
+/* eslint no-unused-vars: 0 */
+
+function createElement (element, makeNested) {
+ if (element instanceof SVG.Element) return element
+
+ if (typeof element === 'object') {
+ return SVG.adopt(element)
+ }
+
+ if (element == null) {
+ return new SVG.Doc()
+ }
+
+ if (typeof element === 'string' && element.charAt(0) !== '<') {
+ return SVG.adopt(document.querySelector(element))
+ }
+
+ var node = SVG.create('svg')
+ node.innerHTML = element
+
+ element = SVG.adopt(node.firstElementChild)
+
+ return element
+}
+
+function isNulledBox (box) {
+ return !box.w && !box.h && !box.x && !box.y
+}
+
+function domContains (node) {
+ return (document.documentElement.contains || function (node) {
+ // This is IE - it does not support contains() for top-level SVGs
+ while (node.parentNode) {
+ node = node.parentNode
+ }
+ return node === document
+ }).call(document.documentElement, node)
+}
+
+function pathRegReplace (a, b, c, d) {
+ return c + d.replace(SVG.regex.dots, ' .')
+}
+
+// creates deep clone of array
+function arrayClone (arr) {
+ var clone = arr.slice(0)
+ for (var i = clone.length; i--;) {
+ if (Array.isArray(clone[i])) {
+ clone[i] = arrayClone(clone[i])
+ }
+ }
+ return clone
+}
+
+// tests if a given element is instance of an object
+function is (el, obj) {
+ return el instanceof obj
+}
+
+// tests if a given selector matches an element
+function matches (el, selector) {
+ return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector)
+}
+
+// Convert dash-separated-string to camelCase
+function camelCase (s) {
+ return s.toLowerCase().replace(/-(.)/g, function (m, g) {
+ return g.toUpperCase()
+ })
+}
+
+// Capitalize first letter of a string
+function capitalize (s) {
+ return s.charAt(0).toUpperCase() + s.slice(1)
+}
+
+// Ensure to six-based hex
+function fullHex (hex) {
+ return hex.length === 4
+ ? [ '#',
+ hex.substring(1, 2), hex.substring(1, 2),
+ hex.substring(2, 3), hex.substring(2, 3),
+ hex.substring(3, 4), hex.substring(3, 4)
+ ].join('')
+ : hex
+}
+
+// Component to hex value
+function compToHex (comp) {
+ var hex = comp.toString(16)
+ return hex.length === 1 ? '0' + hex : hex
+}
+
+// Calculate proportional width and height values when necessary
+function proportionalSize (element, width, height) {
+ if (width == null || height == null) {
+ var box = element.bbox()
+
+ if (width == null) {
+ width = box.width / box.height * height
+ } else if (height == null) {
+ height = box.height / box.width * width
+ }
+ }
+
+ return {
+ width: width,
+ height: height
+ }
+}
+
+// Delta transform point
+function deltaTransformPoint (matrix, x, y) {
+ return {
+ x: x * matrix.a + y * matrix.c + 0,
+ y: x * matrix.b + y * matrix.d + 0
+ }
+}
+
+// Map matrix array to object
+function arrayToMatrix (a) {
+ return { a: a[0], b: a[1], c: a[2], d: a[3], e: a[4], f: a[5] }
+}
+
+// Parse matrix if required
+function parseMatrix (matrix) {
+ if (!(matrix instanceof SVG.Matrix)) {
+ matrix = new SVG.Matrix(matrix)
+ }
+
+ return matrix
+}
+
+// Add centre point to transform object
+function ensureCentre (o, target) {
+ o.cx = o.cx == null ? target.bbox().cx : o.cx
+ o.cy = o.cy == null ? target.bbox().cy : o.cy
+}
+
+// PathArray Helpers
+function arrayToString (a) {
+ for (var i = 0, il = a.length, s = ''; i < il; i++) {
+ s += a[i][0]
+
+ if (a[i][1] != null) {
+ s += a[i][1]
+
+ if (a[i][2] != null) {
+ s += ' '
+ s += a[i][2]
+
+ if (a[i][3] != null) {
+ s += ' '
+ s += a[i][3]
+ s += ' '
+ s += a[i][4]
+
+ if (a[i][5] != null) {
+ s += ' '
+ s += a[i][5]
+ s += ' '
+ s += a[i][6]
+
+ if (a[i][7] != null) {
+ s += ' '
+ s += a[i][7]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return s + ' '
+}
+
+// Deep new id assignment
+function assignNewId (node) {
+ // do the same for SVG child nodes as well
+ for (var i = node.children.length - 1; i >= 0; i--) {
+ assignNewId(node.children[i])
+ }
+
+ if (node.id) {
+ return SVG.adopt(node).id(SVG.eid(node.nodeName))
+ }
+
+ return SVG.adopt(node)
+}
+
+// Add more bounding box properties
+function fullBox (b) {
+ if (b.x == null) {
+ b.x = 0
+ b.y = 0
+ b.width = 0
+ b.height = 0
+ }
+
+ b.w = b.width
+ b.h = b.height
+ b.x2 = b.x + b.width
+ b.y2 = b.y + b.height
+ b.cx = b.x + b.width / 2
+ b.cy = b.y + b.height / 2
+
+ return b
+}
+
+// Get id from reference string
+function idFromReference (url) {
+ var m = (url || '').toString().match(SVG.regex.reference)
+
+ if (m) return m[1]
+}
+
+// Create matrix array for looping
+var abcdef = 'abcdef'.split('')
+
+/* globals fullBox, domContains, isNulledBox, Exception */
+
+SVG.Box = SVG.invent({
+ create: function (source) {
+ var base = [0, 0, 0, 0]
+ source = typeof source === 'string' ? source.split(SVG.regex.delimiter).map(parseFloat)
+ : Array.isArray(source) ? source
+ : typeof source === 'object' ? [source.left != null ? source.left
+ : source.x, source.top != null ? source.top : source.y, source.width, source.height]
+ : arguments.length === 4 ? [].slice.call(arguments)
+ : base
+
+ this.x = source[0]
+ this.y = source[1]
+ this.width = source[2]
+ this.height = source[3]
+
+ // add center, right, bottom...
+ fullBox(this)
+ },
+ extend: {
+ // Merge rect box with another, return a new instance
+ merge: function (box) {
+ var x = Math.min(this.x, box.x)
+ var y = Math.min(this.y, box.y)
+
+ return new SVG.Box(
+ x, y,
+ Math.max(this.x + this.width, box.x + box.width) - x,
+ Math.max(this.y + this.height, box.y + box.height) - y
+ )
+ },
+
+ transform: function (m) {
+ var xMin = Infinity
+ var xMax = -Infinity
+ var yMin = Infinity
+ var yMax = -Infinity
+
+ var pts = [
+ new SVG.Point(this.x, this.y),
+ new SVG.Point(this.x2, this.y),
+ new SVG.Point(this.x, this.y2),
+ new SVG.Point(this.x2, this.y2)
+ ]
+
+ pts.forEach(function (p) {
+ p = p.transform(m)
+ xMin = Math.min(xMin, p.x)
+ xMax = Math.max(xMax, p.x)
+ yMin = Math.min(yMin, p.y)
+ yMax = Math.max(yMax, p.y)
+ })
+
+ return new SVG.Box(
+ xMin, yMin,
+ xMax - xMin,
+ yMax - yMin
+ )
+ },
+
+ addOffset: function () {
+ // offset by window scroll position, because getBoundingClientRect changes when window is scrolled
+ this.x += window.pageXOffset
+ this.y += window.pageYOffset
+ return this
+ },
+ toString: function () {
+ return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height
+ },
+ morph: function (x, y, width, height) {
+ this.destination = new SVG.Box(x, y, width, height)
+ return this
+ },
+
+ at: function (pos) {
+ if (!this.destination) return this
+
+ return new SVG.Box(
+ this.x + (this.destination.x - this.x) * pos
+ , this.y + (this.destination.y - this.y) * pos
+ , this.width + (this.destination.width - this.width) * pos
+ , this.height + (this.destination.height - this.height) * pos
+ )
+ }
+ },
+
+ // Define Parent
+ parent: SVG.Element,
+
+ // Constructor
+ construct: {
+ // Get bounding box
+ bbox: function () {
+ var box
+
+ try {
+ // find native bbox
+ box = this.node.getBBox()
+
+ if (isNulledBox(box) && !domContains(this.node)) {
+ throw new Exception('Element not in the dom')
+ }
+ } catch (e) {
+ try {
+ var clone = this.clone(SVG.parser().svg).show()
+ box = clone.node.getBBox()
+ clone.remove()
+ } catch (e) {
+ console.warn('Getting a bounding box of this element is not possible')
+ }
+ }
+
+ return new SVG.Box(box)
+ },
+
+ rbox: function (el) {
+ // IE11 throws an error when element not in dom
+ try {
+ var box = new SVG.Box(this.node.getBoundingClientRect())
+ if (el) return box.transform(el.screenCTM().inverse())
+ return box.addOffset()
+ } catch (e) {
+ return new SVG.Box()
+ }
+ }
+ }
+})
+
+SVG.extend([SVG.Doc, SVG.Nested, SVG.Symbol, SVG.Image, SVG.Pattern, SVG.Marker, SVG.ForeignObject, SVG.View], {
+ viewbox: function (x, y, width, height) {
+ // act as getter
+ if (x == null) return new SVG.Box(this.attr('viewBox'))
+
+ // act as setter
+ return this.attr('viewBox', new SVG.Box(x, y, width, height))
+ }
+})
+
+
+SVG.parser = function () {
+ var b
+
+ if (!SVG.parser.nodes.svg.node.parentNode) {
+ b = document.body || document.documentElement
+ SVG.parser.nodes.svg.addTo(b)
+ }
+
+ return SVG.parser.nodes
+}
+
+SVG.parser.nodes = {
+ svg: new SVG.Nested().size(2, 0).css({
+ opacity: 0,
+ position: 'absolute',
+ left: '-100%',
+ top: '-100%',
+ overflow: 'hidden'
+ })
+}
+
+SVG.parser.nodes.path = SVG.parser.nodes.svg.path().node
+
+
+return SVG
+
+})); \ No newline at end of file
diff --git a/dist/svg.min.js b/dist/svg.min.js
index 8640a12..277bd40 100644
--- a/dist/svg.min.js
+++ b/dist/svg.min.js
@@ -1,2 +1,2 @@
-/*! svg.js v3.0.0 MIT*/;!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t,t.document)}):"object"==typeof exports?module.exports=t.document?e(t,t.document):function(t){return e(t,t.document)}:t.SVG=e(t,t.document)}("undefined"!=typeof window?window:this,function(t,e){function n(t,n){if(t instanceof P.Element)return t;if("object"==typeof t)return P.adopt(t);if(null==t)return new P.Doc;if("string"==typeof t&&"<"!=t.charAt(0))return P.adopt(e.querySelector(t));var i=P.create("svg");return i.innerHTML=t,t=P.adopt(i.firstElementChild)}function i(t){return!(t.w||t.h||t.x||t.y)}function r(t){return(e.documentElement.contains||function(t){for(;t.parentNode;)t=t.parentNode;return t==e}).call(e.documentElement,t)}function s(t,e,n,i){return n+i.replace(P.regex.dots," .")}function a(t){for(var e=t.slice(0),n=e.length;n--;)Array.isArray(e[n])&&(e[n]=a(e[n]));return e}function o(t,e){return t instanceof e}function h(t,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)}function u(t){return t.toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()})}function l(t){return t.charAt(0).toUpperCase()+t.slice(1)}function c(t){return 4==t.length?["#",t.substring(1,2),t.substring(1,2),t.substring(2,3),t.substring(2,3),t.substring(3,4),t.substring(3,4)].join(""):t}function f(t){var e=t.toString(16);return 1==e.length?"0"+e:e}function d(t,e,n){if(null==e||null==n){var i=t.bbox();null==e?e=i.width/i.height*n:null==n&&(n=i.height/i.width*e)}return{width:e,height:n}}function p(t,e,n){return{x:e*t.a+n*t.c+0,y:e*t.b+n*t.d+0}}function x(t){return{a:t[0],b:t[1],c:t[2],d:t[3],e:t[4],f:t[5]}}function m(t){return t instanceof P.Matrix||(t=new P.Matrix(t)),t}function y(t,e){t.cx=null==t.cx?e.bbox().cx:t.cx,t.cy=null==t.cy?e.bbox().cy:t.cy}function v(t){for(var e=0,n=t.length,i="";e<n;e++)i+=t[e][0],null!=t[e][1]&&(i+=t[e][1],null!=t[e][2]&&(i+=" ",i+=t[e][2],null!=t[e][3]&&(i+=" ",i+=t[e][3],i+=" ",i+=t[e][4],null!=t[e][5]&&(i+=" ",i+=t[e][5],i+=" ",i+=t[e][6],null!=t[e][7]&&(i+=" ",i+=t[e][7])))));return i+" "}function g(t){for(var e=t.children.length-1;e>=0;e--)g(t.children[e]);return t.id?P.adopt(t).id(P.eid(t.nodeName)):P.adopt(t)}function w(t){return null==t.x&&(t.x=0,t.y=0,t.width=0,t.height=0),t.w=t.width,t.h=t.height,t.x2=t.x+t.width,t.y2=t.y+t.height,t.cx=t.x+t.width/2,t.cy=t.y+t.height/2,t}function b(t){var e=(t||"").toString().match(P.regex.reference);if(e)return e[1]}var P=this.SVG=function(t){if(P.supported)return t=n(t)};if(P.ns="http://www.w3.org/2000/svg",P.xmlns="http://www.w3.org/2000/xmlns/",P.xlink="http://www.w3.org/1999/xlink",P.svgjs="http://svgjs.com/svgjs",P.supported=function(){return!!e.createElementNS&&!!e.createElementNS(P.ns,"svg").createSVGRect}(),!P.supported)return!1;P.did=1e3,P.eid=function(t){return"Svgjs"+l(t)+P.did++},P.create=function(t){return e.createElementNS(this.ns,t)},P.extend=function(t,e){var n,i;for(t=Array.isArray(t)?t:[t],i=t.length-1;i>=0;i--)if(t[i])for(n in e)t[i].prototype[n]=e[n]},P.invent=function(t){var e="function"==typeof t.create?t.create:function(e){this.constructor.call(this,e||P.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&P.extend(e,t.extend),t.construct&&P.extend(t.parent||P.Container,t.construct),e},P.adopt=function(e){if(!e)return null;if(e.instance)return e.instance;if(!(e instanceof t.SVGElement))return new P.HtmlNode(e);return"svg"==e.nodeName?e.parentNode instanceof t.SVGElement?new P.Nested(e):new P.Doc(e):"linearGradient"==e.nodeName||"radialGradient"==e.nodeName?new P.Gradient(e):P[l(e.nodeName)]?new(P[l(e.nodeName)])(e):new P.Parent(e)},P.regex={numberAndUnit:/^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,reference:/#([a-z0-9\-_]+)/i,transforms:/\)\s*,?\s*/,whitespace:/\s/g,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,isPercent:/^-?[\d\.]+%$/,isImage:/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,delimiter:/[\s,]+/,hyphen:/([^e])\-/gi,pathLetters:/[MLHVCSQTAZ]/gi,isPathLetter:/[MLHVCSQTAZ]/i,numbersWithDots:/((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi,dots:/\./g},P.utils={map:function(t,e){var n,i=t.length,r=[];for(n=0;n<i;n++)r.push(e(t[n]));return r},filter:function(t,e){var n,i=t.length,r=[];for(n=0;n<i;n++)e(t[n])&&r.push(t[n]);return r},radians:function(t){return t%360*Math.PI/180},degrees:function(t){return 180*t/Math.PI%360},filterSVGElements:function(e){return this.filter(e,function(e){return e instanceof t.SVGElement})}},P.defaults={attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"}},P.Color=function(t){var e;this.r=0,this.g=0,this.b=0,t&&("string"==typeof t?P.regex.isRgb.test(t)?(e=P.regex.rgb.exec(t.replace(P.regex.whitespace,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):P.regex.isHex.test(t)&&(e=P.regex.hex.exec(c(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))},P.extend(P.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+f(this.r)+f(this.g)+f(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},morph:function(t){return this.destination=new P.Color(t),this},at:function(t){return this.destination?(t=t<0?0:t>1?1:t,new P.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}}),P.Color.test=function(t){return t+="",P.regex.isHex.test(t)||P.regex.isRgb.test(t)},P.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},P.Color.isColor=function(t){return P.Color.isRgb(t)||P.Color.test(t)},P.Array=function(t,e){t=(t||[]).valueOf(),0==t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},P.extend(P.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],n=this.destination[this.destination.length-1];this.value.length>this.destination.length;)this.destination.push(n);for(;this.value.length<this.destination.length;)this.value.push(e)}return this},settle:function(){for(var t=0,e=this.value.length,n=[];t<e;t++)-1==n.indexOf(this.value[t])&&n.push(this.value[t]);return this.value=n},at:function(t){if(!this.destination)return this;for(var e=0,n=this.value.length,i=[];e<n;e++)i.push(this.value[e]+(this.destination[e]-this.value[e])*t);return new P.Array(i)},toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:t.trim().split(P.regex.delimiter).map(parseFloat)},reverse:function(){return this.value.reverse(),this},clone:function(){var t=new this.constructor;return t.value=a(this.value),t}}),P.PointArray=function(t,e){P.Array.call(this,t,e||[[0,0]])},P.PointArray.prototype=new P.Array,P.PointArray.prototype.constructor=P.PointArray,P.extend(P.PointArray,{toString:function(){for(var t=0,e=this.value.length,n=[];t<e;t++)n.push(this.value[t].join(","));return n.join(" ")},toLine:function(){return{x1:this.value[0][0],y1:this.value[0][1],x2:this.value[1][0],y2:this.value[1][1]}},at:function(t){if(!this.destination)return this;for(var e=0,n=this.value.length,i=[];e<n;e++)i.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 P.PointArray(i)},parse:function(t){var e=[];if(t=t.valueOf(),Array.isArray(t)){if(Array.isArray(t[0]))return t}else t=t.trim().split(P.regex.delimiter).map(parseFloat);t.length%2!=0&&t.pop();for(var n=0,i=t.length;n<i;n+=2)e.push([t[n],t[n+1]]);return e},move:function(t,e){var n=this.bbox();if(t-=n.x,e-=n.y,!isNaN(t)&&!isNaN(e))for(var i=this.value.length-1;i>=0;i--)this.value[i]=[this.value[i][0]+t,this.value[i][1]+e];return this},size:function(t,e){var n,i=this.bbox();for(n=this.value.length-1;n>=0;n--)i.width&&(this.value[n][0]=(this.value[n][0]-i.x)*t/i.width+i.x),i.height&&(this.value[n][1]=(this.value[n][1]-i.y)*e/i.height+i.y);return this},bbox:function(){var t=-1/0,e=-1/0,n=1/0,i=1/0;return this.value.forEach(function(r){t=Math.max(r[0],t),e=Math.max(r[1],e),n=Math.min(r[0],n),i=Math.min(r[1],i)}),{x:n,y:i,width:t-n,height:e-i}}});for(var M={M:function(t,e,n){return e.x=n.x=t[0],e.y=n.y=t[1],["M",e.x,e.y]},L:function(t,e){return e.x=t[0],e.y=t[1],["L",t[0],t[1]]},H:function(t,e){return e.x=t[0],["H",t[0]]},V:function(t,e){return e.y=t[0],["V",t[0]]},C:function(t,e){return e.x=t[4],e.y=t[5],["C",t[0],t[1],t[2],t[3],t[4],t[5]]},S:function(t,e){return e.x=t[2],e.y=t[3],["S",t[0],t[1],t[2],t[3]]},Q:function(t,e){return e.x=t[2],e.y=t[3],["Q",t[0],t[1],t[2],t[3]]},T:function(t,e){return e.x=t[0],e.y=t[1],["T",t[0],t[1]]},Z:function(t,e,n){return e.x=n.x,e.y=n.y,["Z"]},A:function(t,e){return e.x=t[5],e.y=t[6],["A",t[0],t[1],t[2],t[3],t[4],t[5],t[6]]}},A="mlhvqtcsaz".split(""),N=0,C=A.length;N<C;++N)M[A[N]]=function(t){return function(e,n,i){if("H"==t)e[0]=e[0]+n.x;else if("V"==t)e[0]=e[0]+n.y;else if("A"==t)e[5]=e[5]+n.x,e[6]=e[6]+n.y;else for(var r=0,s=e.length;r<s;++r)e[r]=e[r]+(r%2?n.y:n.x);return M[t](e,n,i)}}(A[N].toUpperCase());P.PathArray=function(t,e){P.Array.call(this,t,e||[["M",0,0]])},P.PathArray.prototype=new P.Array,P.PathArray.prototype.constructor=P.PathArray,P.extend(P.PathArray,{toString:function(){return v(this.value)},move:function(t,e){var n=this.bbox();if(t-=n.x,e-=n.y,!isNaN(t)&&!isNaN(e))for(var i,r=this.value.length-1;r>=0;r--)i=this.value[r][0],"M"==i||"L"==i||"T"==i?(this.value[r][1]+=t,this.value[r][2]+=e):"H"==i?this.value[r][1]+=t:"V"==i?this.value[r][1]+=e:"C"==i||"S"==i||"Q"==i?(this.value[r][1]+=t,this.value[r][2]+=e,this.value[r][3]+=t,this.value[r][4]+=e,"C"==i&&(this.value[r][5]+=t,this.value[r][6]+=e)):"A"==i&&(this.value[r][6]+=t,this.value[r][7]+=e);return this},size:function(t,e){var n,i,r=this.bbox();for(n=this.value.length-1;n>=0;n--)i=this.value[n][0],"M"==i||"L"==i||"T"==i?(this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x,this.value[n][2]=(this.value[n][2]-r.y)*e/r.height+r.y):"H"==i?this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x:"V"==i?this.value[n][1]=(this.value[n][1]-r.y)*e/r.height+r.y:"C"==i||"S"==i||"Q"==i?(this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x,this.value[n][2]=(this.value[n][2]-r.y)*e/r.height+r.y,this.value[n][3]=(this.value[n][3]-r.x)*t/r.width+r.x,this.value[n][4]=(this.value[n][4]-r.y)*e/r.height+r.y,"C"==i&&(this.value[n][5]=(this.value[n][5]-r.x)*t/r.width+r.x,this.value[n][6]=(this.value[n][6]-r.y)*e/r.height+r.y)):"A"==i&&(this.value[n][1]=this.value[n][1]*t/r.width,this.value[n][2]=this.value[n][2]*e/r.height,this.value[n][6]=(this.value[n][6]-r.x)*t/r.width+r.x,this.value[n][7]=(this.value[n][7]-r.y)*e/r.height+r.y);return this},equalCommands:function(t){var e,n,i;for(t=new P.PathArray(t),i=this.value.length===t.value.length,e=0,n=this.value.length;i&&e<n;e++)i=this.value[e][0]===t.value[e][0];return i},morph:function(t){return t=new P.PathArray(t),this.equalCommands(t)?this.destination=t:this.destination=null,this},at:function(t){if(!this.destination)return this;var e,n,i,r,s=this.value,a=this.destination.value,o=[],h=new P.PathArray;for(e=0,n=s.length;e<n;e++){for(o[e]=[s[e][0]],i=1,r=s[e].length;i<r;i++)o[e][i]=s[e][i]+(a[e][i]-s[e][i])*t;"A"===o[e][0]&&(o[e][4]=+(0!=o[e][4]),o[e][5]=+(0!=o[e][5]))}return h.value=o,h},parse:function(t){if(t instanceof P.PathArray)return t.valueOf();var e,n,i={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7,Z:0};t="string"==typeof t?t.replace(P.regex.numbersWithDots,s).replace(P.regex.pathLetters," $& ").replace(P.regex.hyphen,"$1 -").trim().split(P.regex.delimiter):t.reduce(function(t,e){return[].concat.call(t,e)},[]);var n=[],r=new P.Point,a=new P.Point,o=0,h=t.length;do{P.regex.isPathLetter.test(t[o])?(e=t[o],++o):"M"==e?e="L":"m"==e&&(e="l"),n.push(M[e].call(null,t.slice(o,o+=i[e.toUpperCase()]).map(parseFloat),r,a))}while(h>o);return n},bbox:function(){return P.parser().path.setAttribute("d",this.toString()),P.parser.nodes.path.getBBox()}}),P.Number=P.invent({create:function(t,e){this.value=0,this.unit=e||"","number"==typeof t?this.value=isNaN(t)?0:isFinite(t)?t:t<0?-3.4e38:3.4e38:"string"==typeof t?(e=t.match(P.regex.numberAndUnit))&&(this.value=parseFloat(e[1]),"%"==e[5]?this.value/=100:"s"==e[5]&&(this.value*=1e3),this.unit=e[5]):t instanceof P.Number&&(this.value=t.valueOf(),this.unit=t.unit)},extend:{toString:function(){return("%"==this.unit?~~(1e8*this.value)/1e6:"s"==this.unit?this.value/1e3:this.value)+this.unit},toJSON:function(){return this.toString()},valueOf:function(){return this.value},plus:function(t){return t=new P.Number(t),new P.Number(this+t,this.unit||t.unit)},minus:function(t){return t=new P.Number(t),new P.Number(this-t,this.unit||t.unit)},times:function(t){return t=new P.Number(t),new P.Number(this*t,this.unit||t.unit)},divide:function(t){return t=new P.Number(t),new P.Number(this/t,this.unit||t.unit)},to:function(t){var e=new P.Number(this);return"string"==typeof t&&(e.unit=t),e},morph:function(t){return this.destination=new P.Number(t),t.relative&&(this.destination.value+=this.value),this},at:function(t){return this.destination?new P.Number(this.destination).minus(this).times(t).plus(this):this}}}),P.HtmlNode=P.invent({create:function(t){this.node=t},extend:{add:function(t,e){return t=n(t),t instanceof P.Nested&&(t=new P.Doc(t.node),t.setData(JSON.parse(t.node.getAttribute("svgjs:data"))||{})),null==e?this.node.appendChild(t.node):t.node!=this.node.children[e]&&this.node.insertBefore(t.node,this.node.children[e]),this},put:function(t,e){return this.add(t,e),t}}}),P.Element=P.invent({create:function(t){this._event=null,this.dom={},(this.node=t)&&(this.type=t.nodeName,this.node.instance=this,t.hasAttribute("svgjs:data")&&this.setData(JSON.parse(t.getAttribute("svgjs:data"))||{}))},extend:{x:function(t){return this.attr("x",t)},y:function(t){return 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 n=d(this,t,e);return this.width(new P.Number(n.width)).height(new P.Number(n.height))},clone:function(t){this.writeDataToDom();var e=g(this.node.cloneNode(!0));return t?t.add(e):this.after(e),e},remove:function(){return this.parent()&&this.parent().removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return n(t).put(this)},putIn:function(t){return n(t).add(this)},id:function(t){return void 0!==t||this.node.id||(this.node.id=P.eid(this.type)),this.attr("id",t)},inside:function(t,e){var n=this.bbox();return t>n.x&&e>n.y&&t<n.x+n.width&&e<n.y+n.height},show:function(){return this.css("display","")},hide:function(){return this.css("display","none")},visible:function(){return"none"!=this.css("display")},toString:function(){return this.id()},classes:function(){var t=this.attr("class");return null==t?[]:t.trim().split(P.regex.delimiter)},hasClass:function(t){return-1!=this.classes().indexOf(t)},addClass:function(t){if(!this.hasClass(t)){var e=this.classes();e.push(t),this.attr("class",e.join(" "))}return this},removeClass:function(t){return this.hasClass(t)&&this.attr("class",this.classes().filter(function(e){return e!=t}).join(" ")),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t)},reference:function(t){return P.get(this.attr(t))},parent:function(e){var n=this;if(!n.node.parentNode)return null;if(n=P.adopt(n.node.parentNode),!e)return n;for(;n&&n.node instanceof t.SVGElement;){if("string"==typeof e?n.matches(e):n instanceof e)return n;n=P.adopt(n.node.parentNode)}},doc:function(){return this instanceof P.Doc?this:this.parent(P.Doc)},defs:function(){return this.doc().defs()},parents:function(t){var e=[],n=this;do{if(!(n=n.parent(t))||!n.node)break;e.push(n)}while(n.parent);return e},matches:function(t){return h(this.node,t)},native:function(){return this.node},svg:function(t){var n,i;if(!(t&&this instanceof P.Parent))return this.writeDataToDom(),this.node.outerHTML;for(n=e.createElementNS(P.ns,"svg"),n.innerHTML=t,i=n.children.length;i--;)this.node.appendChild(n.firstElementChild);return this},writeDataToDom:function(){return this.is(P.Parent)&&this.each(function(){this.writeDataToDom()}),this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttribute("svgjs:data",JSON.stringify(this.dom)),this},setData:function(t){return this.dom=t,this},is:function(t){return o(this,t)}}}),P.easing={"-":function(t){return t},"<>":function(t){return-Math.cos(t*Math.PI)/2+.5},">":function(t){return Math.sin(t*Math.PI/2)},"<":function(t){return 1-Math.cos(t*Math.PI/2)}},P.morph=function(t){return function(e,n){return new P.MorphObj(e,n).at(t)}},P.Situation=P.invent({create:function(t){this.init=!1,this.reversed=!1,this.reversing=!1,this.duration=new P.Number(t.duration).valueOf(),this.delay=new P.Number(t.delay).valueOf(),this.start=+new Date+this.delay,this.finish=this.start+this.duration,this.ease=t.ease,this.loop=0,this.loops=!1,this.animations={},this.attrs={},this.styles={},this.transforms=[],this.once={}}}),P.FX=P.invent({create:function(t){this._target=t,this.situations=[],this.active=!1,this.situation=null,this.paused=!1,this.lastPos=0,this.pos=0,this.absPos=0,this._speed=1},extend:{animate:function(t,e,n){"object"==typeof t&&(e=t.ease,n=t.delay,t=t.duration);var i=new P.Situation({duration:t||1e3,delay:n||0,ease:P.easing[e||"-"]||e});return this.queue(i),this},delay:function(t){var e=new P.Situation({duration:t,delay:0,ease:P.easing["-"]});return this.queue(e)},target:function(t){return t&&t instanceof P.Element?(this._target=t,this):this._target},timeToAbsPos:function(t){return(t-this.situation.start)/(this.situation.duration/this._speed)},absPosToTime:function(t){return this.situation.duration/this._speed*t+this.situation.start},startAnimFrame:function(){this.stopAnimFrame(),this.animationFrame=t.requestAnimationFrame(function(){this.step()}.bind(this))},stopAnimFrame:function(){t.cancelAnimationFrame(this.animationFrame)},start:function(){return!this.active&&this.situation&&(this.active=!0,this.startCurrent()),this},startCurrent:function(){return this.situation.start=+new Date+this.situation.delay/this._speed,this.situation.finish=this.situation.start+this.situation.duration/this._speed,this.initAnimations().step()},queue:function(t){return("function"==typeof t||t instanceof P.Situation)&&this.situations.push(t),this.situation||(this.situation=this.situations.shift()),this},dequeue:function(){return this.stop(),this.situation=this.situations.shift(),this.situation&&(this.situation instanceof P.Situation?this.start():this.situation.call(this)),this},initAnimations:function(){var t,e,n,i=this.situation;if(i.init)return this;for(t in i.animations)for(n=this.target()[t](),Array.isArray(n)||(n=[n]),Array.isArray(i.animations[t])||(i.animations[t]=[i.animations[t]]),e=n.length;e--;)i.animations[t][e]instanceof P.Number&&(n[e]=new P.Number(n[e])),i.animations[t][e]=n[e].morph(i.animations[t][e]);for(t in i.attrs)i.attrs[t]=new P.MorphObj(this.target().attr(t),i.attrs[t]);for(t in i.styles)i.styles[t]=new P.MorphObj(this.target().css(t),i.styles[t]);return i.initialTransformation=this.target().matrixify(),i.init=!0,this},clearQueue:function(){return this.situations=[],this},clearCurrent:function(){return this.situation=null,this},stop:function(t,e){var n=this.active;return this.active=!1,e&&this.clearQueue(),t&&this.situation&&(!n&&this.startCurrent(),this.atEnd()),this.stopAnimFrame(),this.clearCurrent()},reset:function(){if(this.situation){var t=this.situation;this.stop(),this.situation=t,this.atStart()}return this},finish:function(){for(this.stop(!0,!1);this.dequeue().situation&&this.stop(!0,!1););return this.clearQueue().clearCurrent(),this},atStart:function(){return this.at(0,!0)},atEnd:function(){return!0===this.situation.loops&&(this.situation.loops=this.situation.loop+1),"number"==typeof this.situation.loops?this.at(this.situation.loops,!0):this.at(1,!0)},at:function(t,e){var n=this.situation.duration/this._speed;return this.absPos=t,e||(this.situation.reversed&&(this.absPos=1-this.absPos),this.absPos+=this.situation.loop),this.situation.start=+new Date-this.absPos*n,this.situation.finish=this.situation.start+n,this.step(!0)},speed:function(t){return 0===t?this.pause():t?(this._speed=t,this.at(this.absPos,!0)):this._speed},loop:function(t,e){var n=this.last();return n.loops=null==t||t,n.loop=0,e&&(n.reversing=!0),this},pause:function(){return this.paused=!0,this.stopAnimFrame(),this},play:function(){return this.paused?(this.paused=!1,this.at(this.absPos,!0)):this},reverse:function(t){var e=this.last();return e.reversed=void 0===t?!e.reversed:t,this},progress:function(t){return t?this.situation.ease(this.pos):this.pos},after:function(t){var e=this.last(),n=function n(i){i.detail.situation==e&&(t.call(this,e),this.off("finished.fx",n))};return this.target().on("finished.fx",n),this._callStart()},during:function(t){var e=this.last(),n=function(n){n.detail.situation==e&&t.call(this,n.detail.pos,P.morph(n.detail.pos),n.detail.eased,e)};return this.target().off("during.fx",n).on("during.fx",n),this.after(function(){this.off("during.fx",n)}),this._callStart()},afterAll:function(t){var e=function e(n){t.call(this),this.off("allfinished.fx",e)};return this.target().off("allfinished.fx",e).on("allfinished.fx",e),this._callStart()},duringAll:function(t){var e=function(e){t.call(this,e.detail.pos,P.morph(e.detail.pos),e.detail.eased,e.detail.situation)};return this.target().off("during.fx",e).on("during.fx",e),this.afterAll(function(){this.off("during.fx",e)}),this._callStart()},last:function(){return this.situations.length?this.situations[this.situations.length-1]:this.situation},add:function(t,e,n){return this.last()[n||"animations"][t]=e,this._callStart()},step:function(t){if(t||(this.absPos=this.timeToAbsPos(+new Date)),!1!==this.situation.loops){var e,n,i;e=Math.max(this.absPos,0),n=Math.floor(e),!0===this.situation.loops||n<this.situation.loops?(this.pos=e-n,i=this.situation.loop,this.situation.loop=n):(this.absPos=this.situation.loops,this.pos=1,i=this.situation.loop-1,this.situation.loop=this.situation.loops),this.situation.reversing&&(this.situation.reversed=this.situation.reversed!=Boolean((this.situation.loop-i)%2))}else this.absPos=Math.min(this.absPos,1),this.pos=this.absPos;this.pos<0&&(this.pos=0),this.situation.reversed&&(this.pos=1-this.pos);var r=this.situation.ease(this.pos);for(var s in this.situation.once)s>this.lastPos&&s<=r&&(this.situation.once[s].call(this.target(),this.pos,r),delete this.situation.once[s]);return this.active&&this.target().fire("during",{pos:this.pos,eased:r,fx:this,situation:this.situation}),this.situation?(this.eachAt(),1==this.pos&&!this.situation.reversed||this.situation.reversed&&0==this.pos?(this.stopAnimFrame(),this.target().fire("finished",{fx:this,situation:this.situation}),this.situations.length||(this.target().fire("allfinished"),this.situations.length||(this.target().off(".fx"),this.active=!1)),this.active?this.dequeue():this.clearCurrent()):!this.paused&&this.active&&this.startAnimFrame(),this.lastPos=r,this):this},eachAt:function(){var t,e,n,i=this,r=this.target(),s=this.situation;for(t in s.animations)n=[].concat(s.animations[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(s.ease(i.pos),i.pos):t}),r[t].apply(r,n);for(t in s.attrs)n=[t].concat(s.attrs[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(s.ease(i.pos),i.pos):t}),r.attr.apply(r,n);for(t in s.styles)n=[t].concat(s.styles[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(s.ease(i.pos),i.pos):t}),r.css.apply(r,n);if(s.transforms.length){for(n=s.initialTransformation,t=0,e=s.transforms.length;t<e;t++){var a=s.transforms[t];a instanceof P.Matrix?n=a.relative?n.multiply((new P.Matrix).morph(a).at(s.ease(this.pos))):n.morph(a).at(s.ease(this.pos)):(a.relative||a.undo(n.extract()),n=n.multiply(a.at(s.ease(this.pos))))}r.matrix(n)}return this},once:function(t,e,n){var i=this.last();return n||(t=i.ease(t)),i.once[t]=e,this},_callStart:function(){return setTimeout(function(){this.start()}.bind(this),0),this}},parent:P.Element,construct:{animate:function(t,e,n){return(this.fx||(this.fx=new P.FX(this))).animate(t,e,n)},delay:function(t){return(this.fx||(this.fx=new P.FX(this))).delay(t)},stop:function(t,e){return this.fx&&this.fx.stop(t,e),this},finish:function(){return this.fx&&this.fx.finish(),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this},speed:function(t){if(this.fx){if(null==t)return this.fx.speed();this.fx.speed(t)}return this}}}),P.MorphObj=P.invent({create:function(t,e){return P.Color.isColor(e)?new P.Color(t).morph(e):P.regex.delimiter.test(t)?new P.Array(t).morph(e):P.regex.numberAndUnit.test(e)?new P.Number(t).morph(e):(this.value=t,void(this.destination=e))},extend:{at:function(t,e){return e<1?this.value:this.destination},valueOf:function(){return this.value}}}),P.extend(P.FX,{attr:function(t,e,n){if("object"==typeof t)for(var i in t)this.attr(i,t[i]);else this.add(t,e,"attrs");return this},css:function(t,e){if("object"==typeof t)for(var n in t)this.css(n,t[n]);else this.add(t,e,"styles");return this},x:function(t,e){if(this.target()instanceof P.G)return this.transform({x:t},e),this;var n=new P.Number(t);return n.relative=e,this.add("x",n)},y:function(t,e){if(this.target()instanceof P.G)return this.transform({y:t},e),this;var n=new P.Number(t);return n.relative=e,this.add("y",n)},cx:function(t){return this.add("cx",new P.Number(t))},cy:function(t){return this.add("cy",new P.Number(t))},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 P.Text)this.attr("font-size",t);else{var n;t&&e||(n=this.target().bbox()),t||(t=n.width/n.height*e),e||(e=n.height/n.width*t),this.add("width",new P.Number(t)).add("height",new P.Number(e))}return this},width:function(t){return this.add("width",new P.Number(t))},height:function(t){return this.add("height",new P.Number(t))},plot:function(t,e,n,i){return 4==arguments.length?this.plot([t,e,n,i]):this.add("plot",new(this.target().morphArray)(t))},leading:function(t){return this.target().leading?this.add("leading",new P.Number(t)):this},viewbox:function(t,e,n,i){return this.target()instanceof P.Container&&this.add("viewbox",new P.Box(t,e,n,i)),this},update:function(t){if(this.target()instanceof P.Stop){if("number"==typeof t||t instanceof P.Number)return this.update({offset:arguments[0],color:arguments[1],opacity:arguments[2]});null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",t.offset)}return this}}),P.Matrix=P.invent({create:function(t){var e,n=x([1,0,0,1,0,0]);for(t=t instanceof P.Element?t.matrixify():"string"==typeof t?x(t.split(P.regex.delimiter).map(parseFloat)):6==arguments.length?x([].slice.call(arguments)):Array.isArray(t)?x(t):"object"==typeof t?t:n,e=S.length-1;e>=0;--e)this[S[e]]=null!=t[S[e]]?t[S[e]]:n[S[e]]},extend:{extract:function(){var t=p(this,0,1),e=p(this,1,0),n=180/Math.PI*Math.atan2(t.y,t.x)-90;return{x:this.e,y:this.f,transformedX:(this.e*Math.cos(n*Math.PI/180)+this.f*Math.sin(n*Math.PI/180))/Math.sqrt(this.a*this.a+this.b*this.b),transformedY:(this.f*Math.cos(n*Math.PI/180)+this.e*Math.sin(-n*Math.PI/180))/Math.sqrt(this.c*this.c+this.d*this.d),skewX:-n,skewY:180/Math.PI*Math.atan2(e.y,e.x),scaleX:Math.sqrt(this.a*this.a+this.b*this.b),scaleY:Math.sqrt(this.c*this.c+this.d*this.d),rotation:n,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f,matrix:new P.Matrix(this)}},clone:function(){return new P.Matrix(this)},morph:function(t){return this.destination=new P.Matrix(t),this},at:function(t){return this.destination?new P.Matrix({a:this.a+(this.destination.a-this.a)*t,b:this.b+(this.destination.b-this.b)*t,c:this.c+(this.destination.c-this.c)*t,d:this.d+(this.destination.d-this.d)*t,e:this.e+(this.destination.e-this.e)*t,f:this.f+(this.destination.f-this.f)*t}):this},multiply:function(t){return new P.Matrix(this.native().multiply(m(t).native()))},inverse:function(){return new P.Matrix(this.native().inverse())},translate:function(t,e){return new P.Matrix(this.native().translate(t||0,e||0))},scale:function(t,e,n,i){return 1==arguments.length?e=t:3==arguments.length&&(i=n,n=e,e=t),this.around(n,i,new P.Matrix(t,0,0,e,0,0))},rotate:function(t,e,n){return t=P.utils.radians(t),this.around(e,n,new P.Matrix(Math.cos(t),Math.sin(t),-Math.sin(t),Math.cos(t),0,0))},flip:function(t,e){return"x"==t?this.scale(-1,1,e,0):"y"==t?this.scale(1,-1,0,e):this.scale(-1,-1,t,null!=e?e:t)},skew:function(t,e,n,i){return 1==arguments.length?e=t:3==arguments.length&&(i=n,n=e,e=t),t=P.utils.radians(t),e=P.utils.radians(e),this.around(n,i,new P.Matrix(1,Math.tan(e),Math.tan(t),1,0,0))},skewX:function(t,e,n){return this.skew(t,0,e,n)},skewY:function(t,e,n){return this.skew(0,t,e,n)},around:function(t,e,n){return this.multiply(new P.Matrix(1,0,0,1,t||0,e||0)).multiply(n).multiply(new P.Matrix(1,0,0,1,-t||0,-e||0))},native:function(){for(var t=P.parser.nodes.svg.node.createSVGMatrix(),e=S.length-1;e>=0;e--)t[S[e]]=this[S[e]];return t},toString:function(){return"matrix("+this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f+")"}},parent:P.Element,construct:{ctm:function(){return new P.Matrix(this.node.getCTM())},screenCTM:function(){if(this instanceof P.Nested){var t=this.rect(1,1),e=t.node.getScreenCTM();return t.remove(),new P.Matrix(e)}return new P.Matrix(this.node.getScreenCTM())}}}),P.Point=P.invent({create:function(t,e){var n,i={x:0,y:0};n=Array.isArray(t)?{x:t[0],y:t[1]}:"object"==typeof t?{x:t.x,y:t.y}:null!=t?{x:t,y:null!=e?e:t}:i,this.x=n.x,this.y=n.y},extend:{clone:function(){return new P.Point(this)},morph:function(t,e){return this.destination=new P.Point(t,e),this},at:function(t){return this.destination?new P.Point({x:this.x+(this.destination.x-this.x)*t,y:this.y+(this.destination.y-this.y)*t}):this},native:function(){var t=P.parser.nodes.svg.node.createSVGPoint();return t.x=this.x,t.y=this.y,t},transform:function(t){return new P.Point(this.native().matrixTransform(t.native()))}}}),P.extend(P.Element,{point:function(t,e){return new P.Point(t,e).transform(this.screenCTM().inverse())}}),P.extend(P.Element,{attr:function(t,e,n){if(null==t){for(t={},e=this.node.attributes,n=e.length-1;n>=0;n--)t[e[n].nodeName]=P.regex.isNumber.test(e[n].nodeValue)?parseFloat(e[n].nodeValue):e[n].nodeValue;return t}if("object"==typeof t)for(e in t)this.attr(e,t[e]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return e=this.node.getAttribute(t),null==e?P.defaults.attrs[t]:P.regex.isNumber.test(e)?parseFloat(e):e;"fill"!=t&&"stroke"!=t||(P.regex.isImage.test(e)&&(e=this.doc().defs().image(e)),e instanceof P.Image&&(e=this.doc().defs().pattern(0,0,function(){this.add(e)}))),"number"==typeof e?e=new P.Number(e):P.Color.isColor(e)?e=new P.Color(e):Array.isArray(e)&&(e=new P.Array(e)),"leading"==t?this.leading&&this.leading(e):"string"==typeof n?this.node.setAttributeNS(n,t,e.toString()):this.node.setAttribute(t,e.toString()),
-!this.rebuild||"font-size"!=t&&"x"!=t||this.rebuild(t,e)}return this}}),P.extend(P.Element,{transform:function(t,e){var n,i,r=this;if("object"!=typeof t)return n=new P.Matrix(r).extract(),"string"==typeof t?n[t]:n;if(n=new P.Matrix(r),e=!!e||!!t.relative,null!=t.a)n=e?n.multiply(new P.Matrix(t)):new P.Matrix(t);else if(null!=t.rotation)y(t,r),n=e?n.rotate(t.rotation,t.cx,t.cy):n.rotate(t.rotation-n.extract().rotation,t.cx,t.cy);else if(null!=t.scale||null!=t.scaleX||null!=t.scaleY){if(y(t,r),t.scaleX=null!=t.scale?t.scale:null!=t.scaleX?t.scaleX:1,t.scaleY=null!=t.scale?t.scale:null!=t.scaleY?t.scaleY:1,!e){var s=n.extract();t.scaleX=1*t.scaleX/s.scaleX,t.scaleY=1*t.scaleY/s.scaleY}n=n.scale(t.scaleX,t.scaleY,t.cx,t.cy)}else if(null!=t.skew||null!=t.skewX||null!=t.skewY){if(y(t,r),t.skewX=null!=t.skew?t.skew:null!=t.skewX?t.skewX:0,t.skewY=null!=t.skew?t.skew:null!=t.skewY?t.skewY:0,!e){var s=n.extract();n=n.multiply((new P.Matrix).skew(s.skewX,s.skewY,t.cx,t.cy).inverse())}n=n.skew(t.skewX,t.skewY,t.cx,t.cy)}else t.flip?("x"==t.flip||"y"==t.flip?t.offset=null==t.offset?r.bbox()["c"+t.flip]:t.offset:null==t.offset?(i=r.bbox(),t.flip=i.cx,t.offset=i.cy):t.flip=t.offset,n=(new P.Matrix).flip(t.flip,t.offset)):null==t.x&&null==t.y||(e?n=n.translate(t.x,t.y):(null!=t.x&&(n.e=t.x),null!=t.y&&(n.f=t.y)));return this.attr("transform",n)}}),P.extend(P.FX,{transform:function(t,e){var n,i,r=this.target();return"object"!=typeof t?(n=new P.Matrix(r).extract(),"string"==typeof t?n[t]:n):(e=!!e||!!t.relative,null!=t.a?n=new P.Matrix(t):null!=t.rotation?(y(t,r),n=new P.Rotate(t.rotation,t.cx,t.cy)):null!=t.scale||null!=t.scaleX||null!=t.scaleY?(y(t,r),t.scaleX=null!=t.scale?t.scale:null!=t.scaleX?t.scaleX:1,t.scaleY=null!=t.scale?t.scale:null!=t.scaleY?t.scaleY:1,n=new P.Scale(t.scaleX,t.scaleY,t.cx,t.cy)):null!=t.skewX||null!=t.skewY?(y(t,r),t.skewX=null!=t.skewX?t.skewX:0,t.skewY=null!=t.skewY?t.skewY:0,n=new P.Skew(t.skewX,t.skewY,t.cx,t.cy)):t.flip?("x"==t.flip||"y"==t.flip?t.offset=null==t.offset?r.bbox()["c"+t.flip]:t.offset:null==t.offset?(i=r.bbox(),t.flip=i.cx,t.offset=i.cy):t.flip=t.offset,n=(new P.Matrix).flip(t.flip,t.offset)):null==t.x&&null==t.y||(n=new P.Translate(t.x,t.y)),n?(n.relative=e,this.last().transforms.push(n),this._callStart()):this)}}),P.extend(P.Element,{untransform:function(){return this.attr("transform",null)},matrixify:function(){return(this.attr("transform")||"").split(P.regex.transforms).slice(0,-1).map(function(t){var e=t.trim().split("(");return[e[0],e[1].split(P.regex.delimiter).map(function(t){return parseFloat(t)})]}).reduce(function(t,e){return"matrix"==e[0]?t.multiply(x(e[1])):t[e[0]].apply(t,e[1])},new P.Matrix)},toParent:function(t){if(this==t)return this;var e=this.screenCTM(),n=t.screenCTM().inverse();return this.addTo(t).untransform().transform(n.multiply(e)),this},toDoc:function(){return this.toParent(this.doc())}}),P.Transformation=P.invent({create:function(t,e){if(arguments.length>1&&"boolean"!=typeof e)return this.constructor.call(this,[].slice.call(arguments));if(Array.isArray(t))for(var n=0,i=this.arguments.length;n<i;++n)this[this.arguments[n]]=t[n];else if("object"==typeof t)for(var n=0,i=this.arguments.length;n<i;++n)this[this.arguments[n]]=t[this.arguments[n]];this.inversed=!1,!0===e&&(this.inversed=!0)},extend:{arguments:[],method:"",at:function(t){for(var e=[],n=0,i=this.arguments.length;n<i;++n)e.push(this[this.arguments[n]]);var r=this._undo||new P.Matrix;return r=(new P.Matrix).morph(P.Matrix.prototype[this.method].apply(r,e)).at(t),this.inversed?r.inverse():r},undo:function(t){for(var e=0,n=this.arguments.length;e<n;++e)t[this.arguments[e]]=void 0===this[this.arguments[e]]?0:t[this.arguments[e]];return t.cx=this.cx,t.cy=this.cy,this._undo=new(P[l(this.method)])(t,!0).at(1),this}}}),P.Translate=P.invent({parent:P.Matrix,inherit:P.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["transformedX","transformedY"],method:"translate"}}),P.Rotate=P.invent({parent:P.Matrix,inherit:P.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["rotation","cx","cy"],method:"rotate",at:function(t){var e=(new P.Matrix).rotate((new P.Number).morph(this.rotation-(this._undo?this._undo.rotation:0)).at(t),this.cx,this.cy);return this.inversed?e.inverse():e},undo:function(t){return this._undo=t,this}}}),P.Scale=P.invent({parent:P.Matrix,inherit:P.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["scaleX","scaleY","cx","cy"],method:"scale"}}),P.Skew=P.invent({parent:P.Matrix,inherit:P.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["skewX","skewY","cx","cy"],method:"skew"}}),P.extend(P.Element,{css:function(t,e){var n,i,r={};if(0==arguments.length)return this.node.style.cssText.split(/\s*;\s*/).filter(function(t){return!!t.length}).forEach(function(t){n=t.split(/\s*:\s*/),r[n[0]]=n[1]}),r;if(arguments.length<2){if(Array.isArray(t)){for(i=t.length;i--;)r[u(t[i])]=this.node.style[u(t[i])];return r}if("string"==typeof t)return this.node.style[u(t)];if("object"==typeof t)for(i in t)this.node.style[u(i)]=null==t[i]||P.regex.isBlank.test(t[i])?"":t[i]}return 2==arguments.length&&(this.node.style[u(t)]=null==e||P.regex.isBlank.test(e)?"":e),this}}),P.Parent=P.invent({create:function(t){this.constructor.call(this,t)},inherit:P.Element,extend:{children:function(){return P.utils.map(this.node.children,function(t){return P.adopt(t)})},add:function(t,e){return t=n(t),null==e?this.node.appendChild(t.node):t.node!=this.node.children[e]&&this.node.insertBefore(t.node,this.node.children[e]),this},put:function(t,e){return this.add(t,e),t.instance||t},has:function(t){return this.index(t)>=0},index:function(t){return[].slice.call(this.node.children).indexOf(t.node)},get:function(t){return P.adopt(this.node.children[t])},first:function(){return this.get(0)},last:function(){return this.get(this.node.children.length-1)},each:function(t,e){var n,i,r=this.children();for(n=0,i=r.length;n<i;n++)r[n]instanceof P.Element&&t.apply(r[n],[n,r]),e&&r[n]instanceof P.Parent&&r[n].each(t,e);return this},removeElement:function(t){return this.node.removeChild(t.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return delete this._defs,this}}}),P.extend(P.Parent,{flatten:function(t){return this instanceof P.Defs?this:(t=t||(this instanceof P.Doc?this:this.parent(P.Parent)),this.each(function(){return this instanceof P.Defs?this:this instanceof P.Parent?this.flatten(t):this.toParent(t)}),this.node.firstElementChild||this.remove(),this)}}),P.Container=P.invent({create:function(t){this.constructor.call(this,t)},inherit:P.Parent}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach(function(t){P.Element.prototype[t]=function(e){return P.on(this,t,e),this}}),P.listeners=[],P.handlerMap=[],P.listenerId=0,P.on=function(t,e,n,i,r){e.split(P.regex.delimiter).forEach(function(e){var s=n.bind(i||t),a=t instanceof P.Element?t.node:t,o=(P.handlerMap.indexOf(a)+1||P.handlerMap.push(a))-1,h=e.split(".")[0],u=e.split(".")[1]||"*";P.listeners[o]=P.listeners[o]||{},P.listeners[o][h]=P.listeners[o][h]||{},P.listeners[o][h][u]=P.listeners[o][h][u]||{},n._svgjsListenerId||(n._svgjsListenerId=++P.listenerId),P.listeners[o][h][u][n._svgjsListenerId]=s,a.addEventListener(h,s,r||!1)})},P.off=function(t,e,n){var i=P.handlerMap.indexOf(t),r=e&&e.split(".")[0],s=e&&e.split(".")[1],a="";if(-1!=i)if(n){if("function"==typeof n&&(n=n._svgjsListenerId),!n)return;P.listeners[i][r]&&P.listeners[i][r][s||"*"]&&(t.removeEventListener(r,P.listeners[i][r][s||"*"][n],!1),delete P.listeners[i][r][s||"*"][n])}else if(s&&r){if(P.listeners[i][r]&&P.listeners[i][r][s]){for(n in P.listeners[i][r][s])P.off(t,[r,s].join("."),n);delete P.listeners[i][r][s]}}else if(s)for(e in P.listeners[i])for(a in P.listeners[i][e])s===a&&P.off(t,[e,s].join("."));else if(r){if(P.listeners[i][r]){for(a in P.listeners[i][r])P.off(t,[r,a].join("."));delete P.listeners[i][r]}}else{for(e in P.listeners[i])P.off(t,e);delete P.listeners[i],delete P.handlerMap[i]}},P.extend(P.Element,{on:function(t,e,n,i){return P.on(this,t,e,n,i),this},off:function(t,e){return P.off(this.node,t,e),this},fire:function(e,n){return e instanceof t.Event?this.node.dispatchEvent(e):this.node.dispatchEvent(e=new t.CustomEvent(e,{detail:n,cancelable:!0})),this._event=e,this},event:function(){return this._event}}),P.Defs=P.invent({create:"defs",inherit:P.Container}),P.G=P.invent({create:"g",inherit:P.Container,extend:{x:function(t){return null==t?this.transform("x"):this.transform({x:t-this.x()},!0)},y:function(t){return null==t?this.transform("y"):this.transform({y:t-this.y()},!0)},cx:function(t){return null==t?this.gbox().cx:this.x(t-this.gbox().width/2)},cy:function(t){return null==t?this.gbox().cy:this.y(t-this.gbox().height/2)},gbox:function(){var t=this.bbox(),e=this.transform();return t.x+=e.x,t.x2+=e.x,t.cx+=e.x,t.y+=e.y,t.y2+=e.y,t.cy+=e.y,t}},construct:{group:function(){return this.put(new P.G)}}}),P.extend(P.Element,{siblings:function(){return this.parent().children()},position:function(){return this.parent().index(this)},next:function(){return this.siblings()[this.position()+1]},prev:function(){return this.siblings()[this.position()-1]},forward:function(){var t=this.position()+1,e=this.parent();return e.removeElement(this).add(this,t),e instanceof P.Doc&&e.node.appendChild(e.defs().node),this},backward:function(){var t=this.position();return t>0&&this.parent().removeElement(this).add(this,t-1),this},front:function(){var t=this.parent();return t.node.appendChild(this.node),t instanceof P.Doc&&t.node.appendChild(t.defs().node),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}}),P.Mask=P.invent({create:"mask",inherit:P.Container,extend:{remove:function(){return this.targets().forEach(function(t){t.unmask()}),P.Element.prototype.remove.call(this)},targets:function(){return P.select('svg [mask*="'+this.id()+'"]')}},construct:{mask:function(){return this.defs().put(new P.Mask)}}}),P.extend(P.Element,{maskWith:function(t){var e=t instanceof P.Mask?t:this.parent().mask().add(t);return this.attr("mask",'url("#'+e.id()+'")')},unmask:function(){return this.attr("mask",null)},masker:function(){return this.reference("mask")}}),P.ClipPath=P.invent({create:"clipPath",inherit:P.Container,extend:{remove:function(){return this.targets().forEach(function(t){t.unclip()}),P.Element.prototype.remove.call(this)},targets:function(){return P.select('svg [clip-path*="'+this.id()+'"]')}},construct:{clip:function(){return this.defs().put(new P.ClipPath)}}}),P.extend(P.Element,{clipWith:function(t){var e=t instanceof P.ClipPath?t:this.parent().clip().add(t);return this.attr("clip-path",'url("#'+e.id()+'")')},unclip:function(){return this.attr("clip-path",null)},clipper:function(){return this.reference("clip-path")}}),P.Gradient=P.invent({create:function(t){this.constructor.call(this,"object"==typeof t?t:P.create(t+"Gradient"))},inherit:P.Container,extend:{stop:function(t,e,n){return this.put(new P.Stop).update(t,e,n)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},url:function(){return"url(#"+this.id()+")"},toString:function(){return this.url()},attr:function(t,e,n){return"transform"==t&&(t="gradientTransform"),P.Container.prototype.attr.call(this,t,e,n)}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),P.extend([P.Gradient,P.FX],{from:function(t,e){return"radialGradient"==(this._target||this).type?this.attr({fx:new P.Number(t),fy:new P.Number(e)}):this.attr({x1:new P.Number(t),y1:new P.Number(e)})},to:function(t,e){return"radialGradient"==(this._target||this).type?this.attr({cx:new P.Number(t),cy:new P.Number(e)}):this.attr({x2:new P.Number(t),y2:new P.Number(e)})}}),P.extend(P.Defs,{gradient:function(t,e){return this.put(new P.Gradient(t)).update(e)}}),P.Stop=P.invent({create:"stop",inherit:P.Element,extend:{update:function(t){return("number"==typeof t||t instanceof P.Number)&&(t={offset:arguments[0],color:arguments[1],opacity:arguments[2]}),null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new P.Number(t.offset)),this}}}),P.Pattern=P.invent({create:"pattern",inherit:P.Container,extend:{url:function(){return"url(#"+this.id()+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.url()},attr:function(t,e,n){return"transform"==t&&(t="patternTransform"),P.Container.prototype.attr.call(this,t,e,n)}},construct:{pattern:function(t,e,n){return this.defs().pattern(t,e,n)}}}),P.extend(P.Defs,{pattern:function(t,e,n){return this.put(new P.Pattern).update(n).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),P.Doc=P.invent({create:function(t){this.constructor.call(this,t||P.create("svg")),this.namespace().defs()},inherit:P.Container,extend:{namespace:function(){return this.attr({xmlns:P.ns,version:"1.1"}).attr("xmlns:xlink",P.xlink,P.xmlns).attr("xmlns:svgjs",P.svgjs,P.xmlns)},defs:function(){return P.adopt(this.node.getElementsByTagName("defs")[0])||this.put(new P.Defs)},parent:function(){return"#document"==this.node.parentNode.nodeName?null:this.node.parentNode},remove:function(){return this.parent()&&this.parent().removeChild(this.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this},toNested:function(){var t=P.create("svg");return this.node.instance=null,t.appendChild(this.node),P.adopt(this.node)}}}),P.Shape=P.invent({create:function(t){this.constructor.call(this,t)},inherit:P.Element}),P.Bare=P.invent({create:function(t,e){if(this.constructor.call(this,P.create(t)),e)for(var n in e.prototype)"function"==typeof e.prototype[n]&&(this[n]=e.prototype[n])},inherit:P.Element,extend:{words:function(t){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this.node.appendChild(e.createTextNode(t)),this}}}),P.extend(P.Parent,{element:function(t,e){return this.put(new P.Bare(t,e))}}),P.Symbol=P.invent({create:"symbol",inherit:P.Container,construct:{symbol:function(){return this.put(new P.Symbol)}}}),P.Use=P.invent({create:"use",inherit:P.Shape,extend:{element:function(t,e){return this.attr("href",(e||"")+"#"+t,P.xlink)}},construct:{use:function(t,e){return this.put(new P.Use).element(t,e)}}}),P.Rect=P.invent({create:"rect",inherit:P.Shape,construct:{rect:function(t,e){return this.put(new P.Rect).size(t,e)}}}),P.Circle=P.invent({create:"circle",inherit:P.Shape,construct:{circle:function(t){return this.put(new P.Circle).rx(new P.Number(t).divide(2)).move(0,0)}}}),P.extend([P.Circle,P.FX],{rx:function(t){return this.attr("r",t)},ry:function(t){return this.rx(t)}}),P.Ellipse=P.invent({create:"ellipse",inherit:P.Shape,construct:{ellipse:function(t,e){return this.put(new P.Ellipse).size(t,e).move(0,0)}}}),P.extend([P.Ellipse,P.Rect,P.FX],{rx:function(t){return this.attr("rx",t)},ry:function(t){return this.attr("ry",t)}}),P.extend([P.Circle,P.Ellipse],{x:function(t){return null==t?this.cx()-this.rx():this.cx(t+this.rx())},y:function(t){return null==t?this.cy()-this.ry():this.cy(t+this.ry())},cx:function(t){return null==t?this.attr("cx"):this.attr("cx",t)},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",t)},width:function(t){return null==t?2*this.rx():this.rx(new P.Number(t).divide(2))},height:function(t){return null==t?2*this.ry():this.ry(new P.Number(t).divide(2))},size:function(t,e){var n=d(this,t,e);return this.rx(new P.Number(n.width).divide(2)).ry(new P.Number(n.height).divide(2))}}),P.Line=P.invent({create:"line",inherit:P.Shape,extend:{array:function(){return new P.PointArray([[this.attr("x1"),this.attr("y1")],[this.attr("x2"),this.attr("y2")]])},plot:function(t,e,n,i){return null==t?this.array():(t=void 0!==e?{x1:t,y1:e,x2:n,y2:i}:new P.PointArray(t).toLine(),this.attr(t))},move:function(t,e){return this.attr(this.array().move(t,e).toLine())},size:function(t,e){var n=d(this,t,e);return this.attr(this.array().size(n.width,n.height).toLine())}},construct:{line:function(t,e,n,i){return P.Line.prototype.plot.apply(this.put(new P.Line),null!=t?[t,e,n,i]:[0,0,0,0])}}}),P.Polyline=P.invent({create:"polyline",inherit:P.Shape,construct:{polyline:function(t){return this.put(new P.Polyline).plot(t||new P.PointArray)}}}),P.Polygon=P.invent({create:"polygon",inherit:P.Shape,construct:{polygon:function(t){return this.put(new P.Polygon).plot(t||new P.PointArray)}}}),P.extend([P.Polyline,P.Polygon],{array:function(){return this._array||(this._array=new P.PointArray(this.attr("points")))},plot:function(t){return null==t?this.array():this.clear().attr("points","string"==typeof t?t:this._array=new P.PointArray(t))},clear:function(){return delete this._array,this},move:function(t,e){return this.attr("points",this.array().move(t,e))},size:function(t,e){var n=d(this,t,e);return this.attr("points",this.array().size(n.width,n.height))}}),P.extend([P.Line,P.Polyline,P.Polygon],{morphArray:P.PointArray,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)}}),P.Path=P.invent({create:"path",inherit:P.Shape,extend:{morphArray:P.PathArray,array:function(){return this._array||(this._array=new P.PathArray(this.attr("d")))},plot:function(t){return null==t?this.array():this.clear().attr("d","string"==typeof t?t:this._array=new P.PathArray(t))},clear:function(){return delete this._array,this},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 n=d(this,t,e);return this.attr("d",this.array().size(n.width,n.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 P.Path).plot(t||new P.PathArray)}}}),P.Image=P.invent({create:"image",inherit:P.Shape,extend:{load:function(e,n){if(!e)return this;var i=new t.Image;return P.on(i,"load",function(t){var r=this.parent(P.Pattern);0==this.width()&&0==this.height()&&this.size(i.width,i.height),r instanceof P.Pattern&&0==r.width()&&0==r.height()&&r.size(this.width(),this.height()),"function"==typeof n&&n.call(this,{width:i.width,height:i.height,ratio:i.width/i.height,url:e})},this),P.on(i,"load error",function(){P.off(i)}),this.attr("href",i.src=e,P.xlink)}},construct:{image:function(t,e){return this.put(new P.Image).size(0,0).load(t,e)}}}),P.Text=P.invent({create:function(t){this.constructor.call(this,t||P.create("text")),this.dom.leading=new P.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",P.defaults.attrs["font-family"])},inherit:P.Parent,extend:{x:function(t){return null==t?this.attr("x"):this.attr("x",t)},y:function(t){var e=this.attr("y"),n="number"==typeof e?e-this.bbox().y:0;return null==t?"number"==typeof e?e-n:e:this.attr("y","number"==typeof t?t+n:t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)},text:function(t){if(void 0===t){for(var t="",e=this.node.childNodes,n=0,i=0,r=e.length;i<r;++i)"textPath"!=e[i].nodeName?(i!=n&&3!=e[i].nodeType&&1==P.adopt(e[i]).dom.newLined&&(t+="\n"),t+=e[i].textContent):0==i&&(n=1);return t}if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{t=t.split("\n");for(var i=0,s=t.length;i<s;i++)this.tspan(t[i]).newLine()}return this.build(!1).rebuild()},size:function(t){return this.attr("font-size",t).rebuild()},leading:function(t){return null==t?this.dom.leading:(this.dom.leading=new P.Number(t),this.rebuild())},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this,n=0,i=this.dom.leading*new P.Number(this.attr("font-size"));this.each(function(){this.dom.newLined&&(this.attr("x",e.attr("x")),"\n"==this.text()?n+=i:(this.attr("dy",i+n),n=0))}),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this},setData:function(t){return this.dom=t,this.dom.leading=new P.Number(t.leading||1.3),this}},construct:{text:function(t){return this.put(new P.Text).text(t)},plain:function(t){return this.put(new P.Text).plain(t)}}}),P.Tspan=P.invent({create:"tspan",inherit:P.Parent,extend:{text:function(t){return null==t?this.node.textContent+(this.dom.newLined?"\n":""):("function"==typeof t?t.call(this,this):this.plain(t),this)},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.parent(P.Text);return this.dom.newLined=!0,this.dy(t.dom.leading*t.attr("font-size")).attr("x",t.x())}}}),P.extend([P.Text,P.Tspan],{plain:function(t){return!1===this._build&&this.clear(),this.node.appendChild(e.createTextNode(t)),this},tspan:function(t){var e=new P.Tspan;return this._build||this.clear(),this.node.appendChild(e.node),e.text(t)},length:function(){return this.node.getComputedTextLength()}}),P.TextPath=P.invent({create:"textPath",inherit:P.Text,parent:P.Parent,extend:{morphArray:P.PathArray,array:function(){var t=this.track();return t?t.array():null},plot:function(t){var e=this.track(),n=null;return e&&(n=e.plot(t)),null==t?n:this},track:function(){return this.reference("href")}},construct:{textPath:function(t,e){return this.defs().path(e).text(t).addTo(this)}}}),P.extend([P.Text],{path:function(t){var e=new P.TextPath;return t instanceof P.Path||(t=this.doc().defs().path(t)),e.attr("href","#"+t,P.xlink),this.put(e)},textPath:function(){return this.select("textPath")}}),P.extend([P.Path],{text:function(t){if(t instanceof P.Text){var e=t.text();return t.clear().path(this).text(e)}return this.parent().put(new P.Text).path(this).text(t)}}),P.Nested=P.invent({create:"svg",inherit:P.Container,construct:{nested:function(){return this.put(new P.Nested)}}}),P.A=P.invent({create:"a",inherit:P.Container,extend:{to:function(t){return this.attr("href",t,P.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new P.A).to(t)}}}),P.extend(P.Element,{linkTo:function(t){var e=new P.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent().put(e).put(this)}}),P.Marker=P.invent({create:"marker",inherit:P.Container,extend:{width:function(t){return this.attr("markerWidth",t)},height:function(t){return this.attr("markerHeight",t)},ref:function(t,e){return this.attr("refX",t).attr("refY",e)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return"url(#"+this.id()+")"}},construct:{marker:function(t,e,n){return this.defs().marker(t,e,n)}}}),P.extend(P.Defs,{marker:function(t,e,n){return this.put(new P.Marker).size(t,e).ref(t/2,e/2).viewbox(0,0,t,e).attr("orient","auto").update(n)}}),P.extend([P.Line,P.Polyline,P.Polygon,P.Path],{marker:function(t,e,n,i){var r=["marker"];return"all"!=t&&r.push(t),r=r.join("-"),t=arguments[1]instanceof P.Marker?arguments[1]:this.doc().marker(e,n,i),this.attr(r,t)}});var k={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(t,e){return"color"==e?t:t+"-"+e}};["fill","stroke"].forEach(function(t){var e,n={};n[t]=function(n){if(void 0===n)return this;if("string"==typeof n||P.Color.isRgb(n)||n&&"function"==typeof n.fill)this.attr(t,n);else for(e=k[t].length-1;e>=0;e--)null!=n[k[t][e]]&&this.attr(k.prefix(t,k[t][e]),n[k[t][e]]);return this},P.extend([P.Element,P.FX],n)}),P.extend([P.Element,P.FX],{rotate:function(t,e,n){return this.transform({rotation:t,cx:e,cy:n})},skew:function(t,e,n,i){return 1==arguments.length||3==arguments.length?this.transform({skew:t,cx:e,cy:n}):this.transform({skewX:t,skewY:e,cx:n,cy:i})},scale:function(t,e,n,i){return 1==arguments.length||3==arguments.length?this.transform({scale:t,cx:e,cy:n}):this.transform({scaleX:t,scaleY:e,cx:n,cy:i})},translate:function(t,e){return this.transform({x:t,y:e})},flip:function(t,e){return e="number"==typeof t?t:e,this.transform({flip:t||"both",offset:e})},matrix:function(t){return this.attr("transform",new P.Matrix(6==arguments.length?[].slice.call(arguments):t))},opacity:function(t){return this.attr("opacity",t)},dx:function(t){return this.x(new P.Number(t).plus(this instanceof P.FX?0:this.x()),!0)},dy:function(t){return this.y(new P.Number(t).plus(this instanceof P.FX?0:this.y()),!0)},dmove:function(t,e){return this.dx(t).dy(e)}}),P.extend([P.Rect,P.Ellipse,P.Circle,P.Gradient,P.FX],{radius:function(t,e){var n=(this._target||this).type;return"radialGradient"==n||"radialGradient"==n?this.attr("r",new P.Number(t)):this.rx(t).ry(null==e?t:e)}}),P.extend(P.Path,{length:function(){return this.node.getTotalLength()},pointAt:function(t){return new P.Point(this.node.getPointAtLength(t))}}),P.extend([P.Parent,P.Text,P.Tspan,P.FX],{font:function(t,e){if("object"==typeof t)for(e in t)this.font(e,t[e]);return"leading"==t?this.leading(e):"anchor"==t?this.attr("text-anchor",e):"size"==t||"family"==t||"weight"==t||"stretch"==t||"variant"==t||"style"==t?this.attr("font-"+t,e):this.attr(t,e)}}),P.extend(P.Element,{data:function(t,e,n){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+t))}catch(e){return this.attr("data-"+t)}else this.attr("data-"+t,null===e?null:!0===n||"string"==typeof e||"number"==typeof e?e:JSON.stringify(e));return this}}),P.extend(P.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={})}}),P.get=function(t){var n=e.getElementById(b(t)||t);return P.adopt(n)},P.select=function(t,n){return P.utils.map((n||e).querySelectorAll(t),function(t){return P.adopt(t)})},P.$$=function(t,n){return P.utils.map((n||e).querySelectorAll(t),function(t){return P.adopt(t)})},P.$=function(t,n){return P.adopt((n||e).querySelector(t))},P.extend(P.Parent,{select:function(t){return P.select(t,this.node)}});var S="abcdef".split("");return P.Box=P.invent({create:function(t){var e=[0,0,0,0];t="string"==typeof t?t.split(P.regex.delimiter).map(parseFloat):Array.isArray(t)?t:"object"==typeof t?[null!=t.left?t.left:t.x,null!=t.top?t.top:t.y,t.width,t.height]:4==arguments.length?[].slice.call(arguments):e,this.x=t[0],this.y=t[1],this.width=t[2],this.height=t[3],w(this)},extend:{merge:function(t){var e=Math.min(this.x,t.x),n=Math.min(this.y,t.y);return new P.Box(e,n,Math.max(this.x+this.width,t.x+t.width)-e,Math.max(this.y+this.height,t.y+t.height)-n)},transform:function(t){var e=1/0,n=-1/0,i=1/0,r=-1/0;return[new P.Point(this.x,this.y),new P.Point(this.x2,this.y),new P.Point(this.x,this.y2),new P.Point(this.x2,this.y2)].forEach(function(s){s=s.transform(t),e=Math.min(e,s.x),n=Math.max(n,s.x),i=Math.min(i,s.y),r=Math.max(r,s.y)}),new P.Box(e,i,n-e,r-i)},addOffset:function(){return this.x+=t.pageXOffset,this.y+=t.pageYOffset,this},toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height},morph:function(t,e,n,i){return this.destination=new P.Box(t,e,n,i),this},at:function(t){return this.destination?new P.Box(this.x+(this.destination.x-this.x)*t,this.y+(this.destination.y-this.y)*t,this.width+(this.destination.width-this.width)*t,this.height+(this.destination.height-this.height)*t):this}},parent:P.Element,construct:{bbox:function(){var t;try{if(t=this.node.getBBox(),i(t)&&!r(this.node))throw new Exception("Element not in the dom")}catch(n){try{var e=this.clone(P.parser().svg).show();t=e.node.getBBox(),e.remove()}catch(t){console.warn("Getting a bounding box of this element is not possible")}}return new P.Box(t)},rbox:function(t){try{var e=new P.Box(this.node.getBoundingClientRect());return t?e.transform(t.screenCTM().inverse()):e.addOffset()}catch(t){return new P.Box}}}}),P.extend([P.Doc,P.Nested,P.Symbol,P.Image,P.Pattern,P.Marker,P.ForeignObject,P.View],{viewbox:function(t,e,n,i){return null==t?new P.Box(this.attr("viewBox")):this.attr("viewBox",new P.Box(t,e,n,i))}}),P.parser=function(){var t;return P.parser.nodes.svg.node.parentNode||(t=e.body||e.documentElement,P.parser.nodes.svg.addTo(t)),P.parser.nodes},P.parser.nodes={svg:(new P.Nested).size(2,0).css({opacity:0,position:"absolute",left:"-100%",top:"-100%",overflow:"hidden"})},P.parser.nodes.path=P.parser.nodes.svg.path().node,P}); \ No newline at end of file
+/*! svg.js v3.0.0 MIT*/;!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t,t.document)}):"object"==typeof exports?module.exports=t.document?e(t,t.document):function(t){return e(t,t.document)}:t.SVG=e(t,t.document)}("undefined"!=typeof window?window:this,function(t,e){function n(t,n){if(t instanceof M.Element)return t;if("object"==typeof t)return M.adopt(t);if(null==t)return new M.Doc;if("string"==typeof t&&"<"!==t.charAt(0))return M.adopt(e.querySelector(t));var i=M.create("svg");return i.innerHTML=t,t=M.adopt(i.firstElementChild)}function i(t){return!(t.w||t.h||t.x||t.y)}function r(t){return(e.documentElement.contains||function(t){for(;t.parentNode;)t=t.parentNode;return t===e}).call(e.documentElement,t)}function s(t,e,n,i){return n+i.replace(M.regex.dots," .")}function a(t){for(var e=t.slice(0),n=e.length;n--;)Array.isArray(e[n])&&(e[n]=a(e[n]));return e}function o(t,e){return t instanceof e}function h(t,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)}function u(t){return t.toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()})}function l(t){return t.charAt(0).toUpperCase()+t.slice(1)}function c(t){return 4===t.length?["#",t.substring(1,2),t.substring(1,2),t.substring(2,3),t.substring(2,3),t.substring(3,4),t.substring(3,4)].join(""):t}function f(t){var e=t.toString(16);return 1===e.length?"0"+e:e}function d(t,e,n){if(null==e||null==n){var i=t.bbox();null==e?e=i.width/i.height*n:null==n&&(n=i.height/i.width*e)}return{width:e,height:n}}function p(t,e,n){return{x:e*t.a+n*t.c+0,y:e*t.b+n*t.d+0}}function x(t){return{a:t[0],b:t[1],c:t[2],d:t[3],e:t[4],f:t[5]}}function m(t){return t instanceof M.Matrix||(t=new M.Matrix(t)),t}function y(t,e){t.cx=null==t.cx?e.bbox().cx:t.cx,t.cy=null==t.cy?e.bbox().cy:t.cy}function v(t){for(var e=0,n=t.length,i="";e<n;e++)i+=t[e][0],null!=t[e][1]&&(i+=t[e][1],null!=t[e][2]&&(i+=" ",i+=t[e][2],null!=t[e][3]&&(i+=" ",i+=t[e][3],i+=" ",i+=t[e][4],null!=t[e][5]&&(i+=" ",i+=t[e][5],i+=" ",i+=t[e][6],null!=t[e][7]&&(i+=" ",i+=t[e][7])))));return i+" "}function g(t){for(var e=t.children.length-1;e>=0;e--)g(t.children[e]);return t.id?M.adopt(t).id(M.eid(t.nodeName)):M.adopt(t)}function w(t){return null==t.x&&(t.x=0,t.y=0,t.width=0,t.height=0),t.w=t.width,t.h=t.height,t.x2=t.x+t.width,t.y2=t.y+t.height,t.cx=t.x+t.width/2,t.cy=t.y+t.height/2,t}function b(t){var e=(t||"").toString().match(M.regex.reference);if(e)return e[1]}if(!e.createElementNS||!e.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect)return{supported:!1};var M=this.SVG=function(t){if(M.supported)return t=n(t)};M.supported=!0,M.ns="http://www.w3.org/2000/svg",M.xmlns="http://www.w3.org/2000/xmlns/",M.xlink="http://www.w3.org/1999/xlink",M.svgjs="http://svgjs.com/svgjs",M.did=1e3,M.eid=function(t){return"Svgjs"+l(t)+M.did++},M.create=function(t){return e.createElementNS(this.ns,t)},M.extend=function(t,e){var n,i;for(t=Array.isArray(t)?t:[t],i=t.length-1;i>=0;i--)if(t[i])for(n in e)t[i].prototype[n]=e[n]},M.invent=function(t){var e="function"==typeof t.create?t.create:function(e){this.constructor(e||M.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&M.extend(e,t.extend),t.construct&&M.extend(t.parent||M.Container,t.construct),e},M.adopt=function(e){if(!e)return null;if(e.instance)return e.instance;if(!(e instanceof t.SVGElement))return new M.HtmlNode(e);return"svg"===e.nodeName?e.parentNode instanceof t.SVGElement?new M.Nested(e):new M.Doc(e):"linearGradient"===e.nodeName||"radialGradient"===e.nodeName?new M.Gradient(e):M[l(e.nodeName)]?new(M[l(e.nodeName)])(e):new M.Parent(e)},M.regex={numberAndUnit:/^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,reference:/#([a-z0-9\-_]+)/i,transforms:/\)\s*,?\s*/,whitespace:/\s/g,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,isPercent:/^-?[\d.]+%$/,isImage:/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,delimiter:/[\s,]+/,hyphen:/([^e])-/gi,pathLetters:/[MLHVCSQTAZ]/gi,isPathLetter:/[MLHVCSQTAZ]/i,numbersWithDots:/((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi,dots:/\./g},M.utils={map:function(t,e){var n,i=t.length,r=[];for(n=0;n<i;n++)r.push(e(t[n]));return r},filter:function(t,e){var n,i=t.length,r=[];for(n=0;n<i;n++)e(t[n])&&r.push(t[n]);return r},radians:function(t){return t%360*Math.PI/180},degrees:function(t){return 180*t/Math.PI%360},filterSVGElements:function(e){return this.filter(e,function(e){return e instanceof t.SVGElement})}},M.defaults={attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"}},M.Color=function(t){var e;this.r=0,this.g=0,this.b=0,t&&("string"==typeof t?M.regex.isRgb.test(t)?(e=M.regex.rgb.exec(t.replace(M.regex.whitespace,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):M.regex.isHex.test(t)&&(e=M.regex.hex.exec(c(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))},M.extend(M.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+f(this.r)+f(this.g)+f(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},morph:function(t){return this.destination=new M.Color(t),this},at:function(t){return this.destination?(t=t<0?0:t>1?1:t,new M.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}}),M.Color.test=function(t){return t+="",M.regex.isHex.test(t)||M.regex.isRgb.test(t)},M.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},M.Color.isColor=function(t){return M.Color.isRgb(t)||M.Color.test(t)},M.Array=function(t,e){t=(t||[]).valueOf(),0===t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},M.extend(M.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],n=this.destination[this.destination.length-1];this.value.length>this.destination.length;)this.destination.push(n);for(;this.value.length<this.destination.length;)this.value.push(e)}return this},settle:function(){for(var t=0,e=this.value.length,n=[];t<e;t++)-1===n.indexOf(this.value[t])&&n.push(this.value[t]);return this.value=n,n},at:function(t){if(!this.destination)return this;for(var e=0,n=this.value.length,i=[];e<n;e++)i.push(this.value[e]+(this.destination[e]-this.value[e])*t);return new M.Array(i)},toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:t.trim().split(M.regex.delimiter).map(parseFloat)},reverse:function(){return this.value.reverse(),this},clone:function(){var t=new this.constructor;return t.value=a(this.value),t}}),M.PointArray=function(t,e){M.Array.call(this,t,e||[[0,0]])},M.PointArray.prototype=new M.Array,M.PointArray.prototype.constructor=M.PointArray,M.extend(M.PointArray,{toString:function(){for(var t=0,e=this.value.length,n=[];t<e;t++)n.push(this.value[t].join(","));return n.join(" ")},toLine:function(){return{x1:this.value[0][0],y1:this.value[0][1],x2:this.value[1][0],y2:this.value[1][1]}},at:function(t){if(!this.destination)return this;for(var e=0,n=this.value.length,i=[];e<n;e++)i.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 M.PointArray(i)},parse:function(t){var e=[];if(t=t.valueOf(),Array.isArray(t)){if(Array.isArray(t[0]))return t}else t=t.trim().split(M.regex.delimiter).map(parseFloat);t.length%2!=0&&t.pop();for(var n=0,i=t.length;n<i;n+=2)e.push([t[n],t[n+1]]);return e},move:function(t,e){var n=this.bbox();if(t-=n.x,e-=n.y,!isNaN(t)&&!isNaN(e))for(var i=this.value.length-1;i>=0;i--)this.value[i]=[this.value[i][0]+t,this.value[i][1]+e];return this},size:function(t,e){var n,i=this.bbox();for(n=this.value.length-1;n>=0;n--)i.width&&(this.value[n][0]=(this.value[n][0]-i.x)*t/i.width+i.x),i.height&&(this.value[n][1]=(this.value[n][1]-i.y)*e/i.height+i.y);return this},bbox:function(){var t=-1/0,e=-1/0,n=1/0,i=1/0;return this.value.forEach(function(r){t=Math.max(r[0],t),e=Math.max(r[1],e),n=Math.min(r[0],n),i=Math.min(r[1],i)}),{x:n,y:i,width:t-n,height:e-i}}});for(var P={M:function(t,e,n){return e.x=n.x=t[0],e.y=n.y=t[1],["M",e.x,e.y]},L:function(t,e){return e.x=t[0],e.y=t[1],["L",t[0],t[1]]},H:function(t,e){return e.x=t[0],["H",t[0]]},V:function(t,e){return e.y=t[0],["V",t[0]]},C:function(t,e){return e.x=t[4],e.y=t[5],["C",t[0],t[1],t[2],t[3],t[4],t[5]]},S:function(t,e){return e.x=t[2],e.y=t[3],["S",t[0],t[1],t[2],t[3]]},Q:function(t,e){return e.x=t[2],e.y=t[3],["Q",t[0],t[1],t[2],t[3]]},T:function(t,e){return e.x=t[0],e.y=t[1],["T",t[0],t[1]]},Z:function(t,e,n){return e.x=n.x,e.y=n.y,["Z"]},A:function(t,e){return e.x=t[5],e.y=t[6],["A",t[0],t[1],t[2],t[3],t[4],t[5],t[6]]}},A="mlhvqtcsaz".split(""),N=0,C=A.length;N<C;++N)P[A[N]]=function(t){return function(e,n,i){if("H"===t)e[0]=e[0]+n.x;else if("V"===t)e[0]=e[0]+n.y;else if("A"===t)e[5]=e[5]+n.x,e[6]=e[6]+n.y;else for(var r=0,s=e.length;r<s;++r)e[r]=e[r]+(r%2?n.y:n.x);return P[t](e,n,i)}}(A[N].toUpperCase());M.PathArray=function(t,e){M.Array.call(this,t,e||[["M",0,0]])},M.PathArray.prototype=new M.Array,M.PathArray.prototype.constructor=M.PathArray,M.extend(M.PathArray,{toString:function(){return v(this.value)},move:function(t,e){var n=this.bbox();if(t-=n.x,e-=n.y,!isNaN(t)&&!isNaN(e))for(var i,r=this.value.length-1;r>=0;r--)i=this.value[r][0],"M"===i||"L"===i||"T"===i?(this.value[r][1]+=t,this.value[r][2]+=e):"H"===i?this.value[r][1]+=t:"V"===i?this.value[r][1]+=e:"C"===i||"S"===i||"Q"===i?(this.value[r][1]+=t,this.value[r][2]+=e,this.value[r][3]+=t,this.value[r][4]+=e,"C"===i&&(this.value[r][5]+=t,this.value[r][6]+=e)):"A"===i&&(this.value[r][6]+=t,this.value[r][7]+=e);return this},size:function(t,e){var n,i,r=this.bbox();for(n=this.value.length-1;n>=0;n--)i=this.value[n][0],"M"===i||"L"===i||"T"===i?(this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x,this.value[n][2]=(this.value[n][2]-r.y)*e/r.height+r.y):"H"===i?this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x:"V"===i?this.value[n][1]=(this.value[n][1]-r.y)*e/r.height+r.y:"C"===i||"S"===i||"Q"===i?(this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x,this.value[n][2]=(this.value[n][2]-r.y)*e/r.height+r.y,this.value[n][3]=(this.value[n][3]-r.x)*t/r.width+r.x,this.value[n][4]=(this.value[n][4]-r.y)*e/r.height+r.y,"C"===i&&(this.value[n][5]=(this.value[n][5]-r.x)*t/r.width+r.x,this.value[n][6]=(this.value[n][6]-r.y)*e/r.height+r.y)):"A"===i&&(this.value[n][1]=this.value[n][1]*t/r.width,this.value[n][2]=this.value[n][2]*e/r.height,this.value[n][6]=(this.value[n][6]-r.x)*t/r.width+r.x,this.value[n][7]=(this.value[n][7]-r.y)*e/r.height+r.y);return this},equalCommands:function(t){var e,n,i;for(t=new M.PathArray(t),i=this.value.length===t.value.length,e=0,n=this.value.length;i&&e<n;e++)i=this.value[e][0]===t.value[e][0];return i},morph:function(t){return t=new M.PathArray(t),this.equalCommands(t)?this.destination=t:this.destination=null,this},at:function(t){if(!this.destination)return this;var e,n,i,r,s=this.value,a=this.destination.value,o=[],h=new M.PathArray;for(e=0,n=s.length;e<n;e++){for(o[e]=[s[e][0]],i=1,r=s[e].length;i<r;i++)o[e][i]=s[e][i]+(a[e][i]-s[e][i])*t;"A"===o[e][0]&&(o[e][4]=+(0!==o[e][4]),o[e][5]=+(0!==o[e][5]))}return h.value=o,h},parse:function(t){if(t instanceof M.PathArray)return t.valueOf();var e,n={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7,Z:0};t="string"==typeof t?t.replace(M.regex.numbersWithDots,s).replace(M.regex.pathLetters," $& ").replace(M.regex.hyphen,"$1 -").trim().split(M.regex.delimiter):t.reduce(function(t,e){return[].concat.call(t,e)},[]);var i=[],r=new M.Point,a=new M.Point,o=0,h=t.length;do{M.regex.isPathLetter.test(t[o])?(e=t[o],++o):"M"===e?e="L":"m"===e&&(e="l"),i.push(P[e].call(null,t.slice(o,o+=n[e.toUpperCase()]).map(parseFloat),r,a))}while(h>o);return i},bbox:function(){return M.parser().path.setAttribute("d",this.toString()),M.parser.nodes.path.getBBox()}}),M.Number=M.invent({create:function(t,e){this.value=0,this.unit=e||"","number"==typeof t?this.value=isNaN(t)?0:isFinite(t)?t:t<0?-3.4e38:3.4e38:"string"==typeof t?(e=t.match(M.regex.numberAndUnit))&&(this.value=parseFloat(e[1]),"%"===e[5]?this.value/=100:"s"===e[5]&&(this.value*=1e3),this.unit=e[5]):t instanceof M.Number&&(this.value=t.valueOf(),this.unit=t.unit)},extend:{toString:function(){return("%"===this.unit?~~(1e8*this.value)/1e6:"s"===this.unit?this.value/1e3:this.value)+this.unit},toJSON:function(){return this.toString()},valueOf:function(){return this.value},plus:function(t){return t=new M.Number(t),new M.Number(this+t,this.unit||t.unit)},minus:function(t){return t=new M.Number(t),new M.Number(this-t,this.unit||t.unit)},times:function(t){return t=new M.Number(t),new M.Number(this*t,this.unit||t.unit)},divide:function(t){return t=new M.Number(t),new M.Number(this/t,this.unit||t.unit)},to:function(t){var e=new M.Number(this);return"string"==typeof t&&(e.unit=t),e},morph:function(t){return this.destination=new M.Number(t),t.relative&&(this.destination.value+=this.value),this},at:function(t){return this.destination?new M.Number(this.destination).minus(this).times(t).plus(this):this}}}),M.HtmlNode=M.invent({create:function(t){this.node=t},extend:{add:function(t,e){return t=n(t),t instanceof M.Nested&&(t=new M.Doc(t.node),t.setData(JSON.parse(t.node.getAttribute("svgjs:data"))||{})),null===e?this.node.appendChild(t.node):t.node!==this.node.children[e]&&this.node.insertBefore(t.node,this.node.children[e]),this},put:function(t,e){return this.add(t,e),t}}}),M.Element=M.invent({create:function(t){this._event=null,this.dom={},this.node=t,this.node&&(this.type=t.nodeName,this.node.instance=this,t.hasAttribute("svgjs:data")&&this.setData(JSON.parse(t.getAttribute("svgjs:data"))||{}))},extend:{x:function(t){return this.attr("x",t)},y:function(t){return 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 n=d(this,t,e);return this.width(new M.Number(n.width)).height(new M.Number(n.height))},clone:function(t){this.writeDataToDom();var e=g(this.node.cloneNode(!0));return t?t.add(e):this.after(e),e},remove:function(){return this.parent()&&this.parent().removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return n(t).put(this)},putIn:function(t){return n(t).add(this)},id:function(t){return void 0!==t||this.node.id||(this.node.id=M.eid(this.type)),this.attr("id",t)},inside:function(t,e){var n=this.bbox();return t>n.x&&e>n.y&&t<n.x+n.width&&e<n.y+n.height},show:function(){return this.css("display","")},hide:function(){return this.css("display","none")},visible:function(){return"none"!==this.css("display")},toString:function(){return this.id()},classes:function(){var t=this.attr("class");return null==t?[]:t.trim().split(M.regex.delimiter)},hasClass:function(t){return-1!==this.classes().indexOf(t)},addClass:function(t){if(!this.hasClass(t)){var e=this.classes();e.push(t),this.attr("class",e.join(" "))}return this},removeClass:function(t){return this.hasClass(t)&&this.attr("class",this.classes().filter(function(e){return e!==t}).join(" ")),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t)},reference:function(t){return M.get(this.attr(t))},parent:function(e){var n=this;if(!n.node.parentNode)return null;if(n=M.adopt(n.node.parentNode),!e)return n;for(;n&&n.node instanceof t.SVGElement;){if("string"==typeof e?n.matches(e):n instanceof e)return n;n=M.adopt(n.node.parentNode)}},doc:function(){return this instanceof M.Doc?this:this.parent(M.Doc)},defs:function(){return this.doc().defs()},parents:function(t){var e=[],n=this;do{if(!(n=n.parent(t))||!n.node)break;e.push(n)}while(n.parent);return e},matches:function(t){return h(this.node,t)},native:function(){return this.node},svg:function(t){var n,i;if(!(t&&this instanceof M.Parent))return this.writeDataToDom(),this.node.outerHTML;for(n=e.createElementNS(M.ns,"svg"),n.innerHTML=t,i=n.children.length;i--;)this.node.appendChild(n.firstElementChild);return this},writeDataToDom:function(){return this.is(M.Parent)&&this.each(function(){this.writeDataToDom()}),this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttribute("svgjs:data",JSON.stringify(this.dom)),this},setData:function(t){return this.dom=t,this},is:function(t){return o(this,t)}}}),M.easing={"-":function(t){return t},"<>":function(t){return-Math.cos(t*Math.PI)/2+.5},">":function(t){return Math.sin(t*Math.PI/2)},"<":function(t){return 1-Math.cos(t*Math.PI/2)}},M.morph=function(t){return function(e,n){return new M.MorphObj(e,n).at(t)}},M.Situation=M.invent({create:function(t){this.init=!1,this.reversed=!1,this.reversing=!1,this.duration=new M.Number(t.duration).valueOf(),this.delay=new M.Number(t.delay).valueOf(),this.start=+new Date+this.delay,this.finish=this.start+this.duration,this.ease=t.ease,this.loop=0,this.loops=!1,this.animations={},this.attrs={},this.styles={},this.transforms=[],this.once={}}}),M.FX=M.invent({create:function(t){this._target=t,this.situations=[],this.active=!1,this.situation=null,this.paused=!1,this.lastPos=0,this.pos=0,this.absPos=0,this._speed=1},extend:{animate:function(t,e,n){"object"==typeof t&&(e=t.ease,n=t.delay,t=t.duration);var i=new M.Situation({duration:t||1e3,delay:n||0,ease:M.easing[e||"-"]||e});return this.queue(i),this},delay:function(t){var e=new M.Situation({duration:t,delay:0,ease:M.easing["-"]});return this.queue(e)},target:function(t){return t&&t instanceof M.Element?(this._target=t,this):this._target},timeToAbsPos:function(t){return(t-this.situation.start)/(this.situation.duration/this._speed)},absPosToTime:function(t){return this.situation.duration/this._speed*t+this.situation.start},startAnimFrame:function(){this.stopAnimFrame(),this.animationFrame=t.requestAnimationFrame(function(){this.step()}.bind(this))},stopAnimFrame:function(){t.cancelAnimationFrame(this.animationFrame)},start:function(){return!this.active&&this.situation&&(this.active=!0,this.startCurrent()),this},startCurrent:function(){return this.situation.start=+new Date+this.situation.delay/this._speed,this.situation.finish=this.situation.start+this.situation.duration/this._speed,this.initAnimations().step()},queue:function(t){return("function"==typeof t||t instanceof M.Situation)&&this.situations.push(t),this.situation||(this.situation=this.situations.shift()),this},dequeue:function(){return this.stop(),this.situation=this.situations.shift(),this.situation&&(this.situation instanceof M.Situation?this.start():this.situation(this)),this},initAnimations:function(){var t,e,n,i=this.situation;if(i.init)return this;for(t in i.animations)for(n=this.target()[t](),Array.isArray(n)||(n=[n]),Array.isArray(i.animations[t])||(i.animations[t]=[i.animations[t]]),e=n.length;e--;)i.animations[t][e]instanceof M.Number&&(n[e]=new M.Number(n[e])),i.animations[t][e]=n[e].morph(i.animations[t][e]);for(t in i.attrs)i.attrs[t]=new M.MorphObj(this.target().attr(t),i.attrs[t]);for(t in i.styles)i.styles[t]=new M.MorphObj(this.target().css(t),i.styles[t]);return i.initialTransformation=this.target().matrixify(),i.init=!0,this},clearQueue:function(){return this.situations=[],this},clearCurrent:function(){return this.situation=null,this},stop:function(t,e){var n=this.active;return this.active=!1,e&&this.clearQueue(),t&&this.situation&&(!n&&this.startCurrent(),this.atEnd()),this.stopAnimFrame(),this.clearCurrent()},reset:function(){if(this.situation){var t=this.situation;this.stop(),this.situation=t,this.atStart()}return this},finish:function(){for(this.stop(!0,!1);this.dequeue().situation&&this.stop(!0,!1););return this.clearQueue().clearCurrent(),this},atStart:function(){return this.at(0,!0)},atEnd:function(){return!0===this.situation.loops&&(this.situation.loops=this.situation.loop+1),"number"==typeof this.situation.loops?this.at(this.situation.loops,!0):this.at(1,!0)},at:function(t,e){var n=this.situation.duration/this._speed;return this.absPos=t,e||(this.situation.reversed&&(this.absPos=1-this.absPos),this.absPos+=this.situation.loop),this.situation.start=+new Date-this.absPos*n,this.situation.finish=this.situation.start+n,this.step(!0)},speed:function(t){return 0===t?this.pause():t?(this._speed=t,this.at(this.absPos,!0)):this._speed},loop:function(t,e){var n=this.last();return n.loops=null==t||t,n.loop=0,e&&(n.reversing=!0),this},pause:function(){return this.paused=!0,this.stopAnimFrame(),this},play:function(){return this.paused?(this.paused=!1,this.at(this.absPos,!0)):this},reverse:function(t){var e=this.last();return e.reversed=void 0===t?!e.reversed:t,this},progress:function(t){return t?this.situation.ease(this.pos):this.pos},after:function(t){function e(i){i.detail.situation===n&&(t.call(this,n),this.off("finished.fx",e))}var n=this.last();return this.target().on("finished.fx",e),this._callStart()},during:function(t){function e(e){e.detail.situation===n&&t.call(this,e.detail.pos,M.morph(e.detail.pos),e.detail.eased,n)}var n=this.last();return this.target().off("during.fx",e).on("during.fx",e),this.after(function(){this.off("during.fx",e)}),this._callStart()},afterAll:function(t){var e=function e(n){t.call(this),this.off("allfinished.fx",e)};return this.target().off("allfinished.fx",e).on("allfinished.fx",e),this._callStart()},duringAll:function(t){var e=function(e){t.call(this,e.detail.pos,M.morph(e.detail.pos),e.detail.eased,e.detail.situation)};return this.target().off("during.fx",e).on("during.fx",e),this.afterAll(function(){this.off("during.fx",e)}),this._callStart()},last:function(){return this.situations.length?this.situations[this.situations.length-1]:this.situation},add:function(t,e,n){return this.last()[n||"animations"][t]=e,this._callStart()},step:function(t){if(t||(this.absPos=this.timeToAbsPos(+new Date)),!1!==this.situation.loops){var e,n,i;e=Math.max(this.absPos,0),n=Math.floor(e),!0===this.situation.loops||n<this.situation.loops?(this.pos=e-n,i=this.situation.loop,this.situation.loop=n):(this.absPos=this.situation.loops,this.pos=1,i=this.situation.loop-1,this.situation.loop=this.situation.loops),this.situation.reversing&&(this.situation.reversed=this.situation.reversed!==Boolean((this.situation.loop-i)%2))}else this.absPos=Math.min(this.absPos,1),this.pos=this.absPos;this.pos<0&&(this.pos=0),this.situation.reversed&&(this.pos=1-this.pos);var r=this.situation.ease(this.pos);for(var s in this.situation.once)s>this.lastPos&&s<=r&&(this.situation.once[s].call(this.target(),this.pos,r),delete this.situation.once[s]);return this.active&&this.target().fire("during",{pos:this.pos,eased:r,fx:this,situation:this.situation}),this.situation?(this.eachAt(),1===this.pos&&!this.situation.reversed||this.situation.reversed&&0===this.pos?(this.stopAnimFrame(),this.target().fire("finished",{fx:this,situation:this.situation}),this.situations.length||(this.target().fire("allfinished"),this.situations.length||(this.target().off(".fx"),this.active=!1)),this.active?this.dequeue():this.clearCurrent()):!this.paused&&this.active&&this.startAnimFrame(),this.lastPos=r,this):this},eachAt:function(){var t,e,n,i=this,r=this.target(),s=this.situation;for(t in s.animations)n=[].concat(s.animations[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(s.ease(i.pos),i.pos):t}),r[t].apply(r,n);for(t in s.attrs)n=[t].concat(s.attrs[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(s.ease(i.pos),i.pos):t}),r.attr.apply(r,n);for(t in s.styles)n=[t].concat(s.styles[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(s.ease(i.pos),i.pos):t}),r.css.apply(r,n);if(s.transforms.length){for(n=s.initialTransformation,t=0,e=s.transforms.length;t<e;t++){var a=s.transforms[t];a instanceof M.Matrix?n=a.relative?n.multiply((new M.Matrix).morph(a).at(s.ease(this.pos))):n.morph(a).at(s.ease(this.pos)):(a.relative||a.undo(n.extract()),n=n.multiply(a.at(s.ease(this.pos))))}r.matrix(n)}return this},once:function(t,e,n){var i=this.last();return n||(t=i.ease(t)),i.once[t]=e,this},_callStart:function(){return setTimeout(function(){this.start()}.bind(this),0),this}},parent:M.Element,construct:{animate:function(t,e,n){return(this.fx||(this.fx=new M.FX(this))).animate(t,e,n)},delay:function(t){return(this.fx||(this.fx=new M.FX(this))).delay(t)},stop:function(t,e){return this.fx&&this.fx.stop(t,e),this},finish:function(){return this.fx&&this.fx.finish(),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this},speed:function(t){if(this.fx){if(null==t)return this.fx.speed();this.fx.speed(t)}return this}}}),M.MorphObj=M.invent({create:function(t,e){return M.Color.isColor(e)?new M.Color(t).morph(e):M.regex.delimiter.test(t)?new M.Array(t).morph(e):M.regex.numberAndUnit.test(e)?new M.Number(t).morph(e):(this.value=t,void(this.destination=e))},extend:{at:function(t,e){return e<1?this.value:this.destination},valueOf:function(){return this.value}}}),M.extend(M.FX,{attr:function(t,e,n){if("object"==typeof t)for(var i in t)this.attr(i,t[i]);else this.add(t,e,"attrs");return this},css:function(t,e){if("object"==typeof t)for(var n in t)this.css(n,t[n]);else this.add(t,e,"styles");return this},x:function(t,e){if(this.target()instanceof M.G)return this.transform({x:t},e),this;var n=new M.Number(t);return n.relative=e,this.add("x",n)},y:function(t,e){if(this.target()instanceof M.G)return this.transform({y:t},e),this;var n=new M.Number(t);return n.relative=e,this.add("y",n)},cx:function(t){return this.add("cx",new M.Number(t))},cy:function(t){return this.add("cy",new M.Number(t))},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 M.Text)this.attr("font-size",t);else{var n;t&&e||(n=this.target().bbox()),t||(t=n.width/n.height*e),e||(e=n.height/n.width*t),this.add("width",new M.Number(t)).add("height",new M.Number(e))}return this},width:function(t){return this.add("width",new M.Number(t))},height:function(t){return this.add("height",new M.Number(t))},plot:function(t,e,n,i){return 4===arguments.length?this.plot([t,e,n,i]):this.add("plot",new(this.target().MorphArray)(t))},leading:function(t){return this.target().leading?this.add("leading",new M.Number(t)):this},viewbox:function(t,e,n,i){return this.target()instanceof M.Container&&this.add("viewbox",new M.Box(t,e,n,i)),this},update:function(t){if(this.target()instanceof M.Stop){if("number"==typeof t||t instanceof M.Number)return this.update({offset:arguments[0],color:arguments[1],opacity:arguments[2]});null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",t.offset)}return this}}),M.Matrix=M.invent({create:function(t){var e,n=x([1,0,0,1,0,0]);for(t=t instanceof M.Element?t.matrixify():"string"==typeof t?x(t.split(M.regex.delimiter).map(parseFloat)):6===arguments.length?x([].slice.call(arguments)):Array.isArray(t)?x(t):"object"==typeof t?t:n,e=S.length-1;e>=0;--e)this[S[e]]=null!=t[S[e]]?t[S[e]]:n[S[e]]},extend:{extract:function(){var t=p(this,0,1),e=p(this,1,0),n=180/Math.PI*Math.atan2(t.y,t.x)-90;return{x:this.e,y:this.f,transformedX:(this.e*Math.cos(n*Math.PI/180)+this.f*Math.sin(n*Math.PI/180))/Math.sqrt(this.a*this.a+this.b*this.b),transformedY:(this.f*Math.cos(n*Math.PI/180)+this.e*Math.sin(-n*Math.PI/180))/Math.sqrt(this.c*this.c+this.d*this.d),skewX:-n,skewY:180/Math.PI*Math.atan2(e.y,e.x),scaleX:Math.sqrt(this.a*this.a+this.b*this.b),scaleY:Math.sqrt(this.c*this.c+this.d*this.d),rotation:n,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f,matrix:new M.Matrix(this)}},clone:function(){return new M.Matrix(this)},morph:function(t){return this.destination=new M.Matrix(t),this},at:function(t){return this.destination?new M.Matrix({a:this.a+(this.destination.a-this.a)*t,b:this.b+(this.destination.b-this.b)*t,c:this.c+(this.destination.c-this.c)*t,d:this.d+(this.destination.d-this.d)*t,e:this.e+(this.destination.e-this.e)*t,f:this.f+(this.destination.f-this.f)*t}):this},multiply:function(t){return new M.Matrix(this.native().multiply(m(t).native()))},inverse:function(){return new M.Matrix(this.native().inverse())},translate:function(t,e){return new M.Matrix(this.native().translate(t||0,e||0))},scale:function(t,e,n,i){return 1===arguments.length?e=t:3===arguments.length&&(i=n,n=e,e=t),this.around(n,i,new M.Matrix(t,0,0,e,0,0))},rotate:function(t,e,n){return t=M.utils.radians(t),this.around(e,n,new M.Matrix(Math.cos(t),Math.sin(t),-Math.sin(t),Math.cos(t),0,0))},flip:function(t,e){return"x"===t?this.scale(-1,1,e,0):"y"===t?this.scale(1,-1,0,e):this.scale(-1,-1,t,null!=e?e:t)},skew:function(t,e,n,i){return 1===arguments.length?e=t:3===arguments.length&&(i=n,n=e,e=t),t=M.utils.radians(t),e=M.utils.radians(e),this.around(n,i,new M.Matrix(1,Math.tan(e),Math.tan(t),1,0,0))},skewX:function(t,e,n){return this.skew(t,0,e,n)},skewY:function(t,e,n){return this.skew(0,t,e,n)},around:function(t,e,n){return this.multiply(new M.Matrix(1,0,0,1,t||0,e||0)).multiply(n).multiply(new M.Matrix(1,0,0,1,-t||0,-e||0))},native:function(){for(var t=M.parser.nodes.svg.node.createSVGMatrix(),e=S.length-1;e>=0;e--)t[S[e]]=this[S[e]];return t},toString:function(){return"matrix("+this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f+")"}},parent:M.Element,construct:{ctm:function(){return new M.Matrix(this.node.getCTM())},screenCTM:function(){if(this instanceof M.Nested){var t=this.rect(1,1),e=t.node.getScreenCTM();return t.remove(),new M.Matrix(e)}return new M.Matrix(this.node.getScreenCTM())}}}),M.Point=M.invent({create:function(t,e){var n,i={x:0,y:0};n=Array.isArray(t)?{x:t[0],y:t[1]}:"object"==typeof t?{x:t.x,y:t.y}:null!=t?{x:t,y:null!=e?e:t}:i,this.x=n.x,this.y=n.y},extend:{clone:function(){return new M.Point(this)},morph:function(t,e){return this.destination=new M.Point(t,e),this},at:function(t){return this.destination?new M.Point({x:this.x+(this.destination.x-this.x)*t,y:this.y+(this.destination.y-this.y)*t}):this},native:function(){var t=M.parser.nodes.svg.node.createSVGPoint();return t.x=this.x,t.y=this.y,t},transform:function(t){return new M.Point(this.native().matrixTransform(t.native()))}}}),M.extend(M.Element,{point:function(t,e){return new M.Point(t,e).transform(this.screenCTM().inverse())}}),M.extend(M.Element,{attr:function(t,e,n){if(null==t){for(t={},e=this.node.attributes,n=e.length-1;n>=0;n--)t[e[n].nodeName]=M.regex.isNumber.test(e[n].nodeValue)?parseFloat(e[n].nodeValue):e[n].nodeValue;return t}if("object"==typeof t)for(e in t)this.attr(e,t[e]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return e=this.node.getAttribute(t),null==e?M.defaults.attrs[t]:M.regex.isNumber.test(e)?parseFloat(e):e;"fill"!==t&&"stroke"!==t||(M.regex.isImage.test(e)&&(e=this.doc().defs().image(e)),e instanceof M.Image&&(e=this.doc().defs().pattern(0,0,function(){this.add(e)}))),"number"==typeof e?e=new M.Number(e):M.Color.isColor(e)?e=new M.Color(e):Array.isArray(e)&&(e=new M.Array(e)),"leading"===t?this.leading&&this.leading(e):"string"==typeof n?this.node.setAttributeNS(n,t,e.toString()):this.node.setAttribute(t,e.toString()),
+!this.rebuild||"font-size"!==t&&"x"!==t||this.rebuild(t,e)}return this}}),M.extend(M.Element,{transform:function(t,e){var n,i,r=this;if("object"!=typeof t)return n=new M.Matrix(r).extract(),"string"==typeof t?n[t]:n;if(n=new M.Matrix(r),e=!!e||!!t.relative,null!=t.a)n=e?n.multiply(new M.Matrix(t)):new M.Matrix(t);else if(null!=t.rotation)y(t,r),n=e?n.rotate(t.rotation,t.cx,t.cy):n.rotate(t.rotation-n.extract().rotation,t.cx,t.cy);else if(null!=t.scale||null!=t.scaleX||null!=t.scaleY){if(y(t,r),t.scaleX=null!=t.scale?t.scale:null!=t.scaleX?t.scaleX:1,t.scaleY=null!=t.scale?t.scale:null!=t.scaleY?t.scaleY:1,!e){var s=n.extract();t.scaleX=1*t.scaleX/s.scaleX,t.scaleY=1*t.scaleY/s.scaleY}n=n.scale(t.scaleX,t.scaleY,t.cx,t.cy)}else if(null!=t.skew||null!=t.skewX||null!=t.skewY){if(y(t,r),t.skewX=null!=t.skew?t.skew:null!=t.skewX?t.skewX:0,t.skewY=null!=t.skew?t.skew:null!=t.skewY?t.skewY:0,!e){var a=n.extract();n=n.multiply((new M.Matrix).skew(a.skewX,a.skewY,a.cx,a.cy).inverse())}n=n.skew(t.skewX,t.skewY,t.cx,t.cy)}else t.flip?("x"===t.flip||"y"===t.flip?t.offset=null==t.offset?r.bbox()["c"+t.flip]:t.offset:null==t.offset?(i=r.bbox(),t.flip=i.cx,t.offset=i.cy):t.flip=t.offset,n=(new M.Matrix).flip(t.flip,t.offset)):null==t.x&&null==t.y||(e?n=n.translate(t.x,t.y):(null!=t.x&&(n.e=t.x),null!=t.y&&(n.f=t.y)));return this.attr("transform",n)}}),M.extend(M.FX,{transform:function(t,e){var n,i,r=this.target();return"object"!=typeof t?(n=new M.Matrix(r).extract(),"string"==typeof t?n[t]:n):(e=!!e||!!t.relative,null!=t.a?n=new M.Matrix(t):null!=t.rotation?(y(t,r),n=new M.Rotate(t.rotation,t.cx,t.cy)):null!=t.scale||null!=t.scaleX||null!=t.scaleY?(y(t,r),t.scaleX=null!=t.scale?t.scale:null!=t.scaleX?t.scaleX:1,t.scaleY=null!=t.scale?t.scale:null!=t.scaleY?t.scaleY:1,n=new M.Scale(t.scaleX,t.scaleY,t.cx,t.cy)):null!=t.skewX||null!=t.skewY?(y(t,r),t.skewX=null!=t.skewX?t.skewX:0,t.skewY=null!=t.skewY?t.skewY:0,n=new M.Skew(t.skewX,t.skewY,t.cx,t.cy)):t.flip?("x"===t.flip||"y"===t.flip?t.offset=null==t.offset?r.bbox()["c"+t.flip]:t.offset:null==t.offset?(i=r.bbox(),t.flip=i.cx,t.offset=i.cy):t.flip=t.offset,n=(new M.Matrix).flip(t.flip,t.offset)):null==t.x&&null==t.y||(n=new M.Translate(t.x,t.y)),n?(n.relative=e,this.last().transforms.push(n),this._callStart()):this)}}),M.extend(M.Element,{untransform:function(){return this.attr("transform",null)},matrixify:function(){return(this.attr("transform")||"").split(M.regex.transforms).slice(0,-1).map(function(t){var e=t.trim().split("(");return[e[0],e[1].split(M.regex.delimiter).map(function(t){return parseFloat(t)})]}).reduce(function(t,e){return"matrix"===e[0]?t.multiply(x(e[1])):t[e[0]].apply(t,e[1])},new M.Matrix)},toParent:function(t){if(this===t)return this;var e=this.screenCTM(),n=t.screenCTM().inverse();return this.addTo(t).untransform().transform(n.multiply(e)),this},toDoc:function(){return this.toParent(this.doc())}}),M.Transformation=M.invent({create:function(t,e){if(arguments.length>1&&"boolean"!=typeof e)return this.constructor.bind(this)([].slice.call(arguments));var n,i;if(Array.isArray(t))for(n=0,i=this.arguments.length;n<i;++n)this[this.arguments[n]]=t[n];else if("object"==typeof t)for(n=0,i=this.arguments.length;n<i;++n)this[this.arguments[n]]=t[this.arguments[n]];this.inversed=!1,!0===e&&(this.inversed=!0)},extend:{arguments:[],method:"",at:function(t){for(var e=[],n=0,i=this.arguments.length;n<i;++n)e.push(this[this.arguments[n]]);var r=this._undo||new M.Matrix;return r=(new M.Matrix).morph(M.Matrix.prototype[this.method].apply(r,e)).at(t),this.inversed?r.inverse():r},undo:function(t){for(var e=0,n=this.arguments.length;e<n;++e)t[this.arguments[e]]=void 0===this[this.arguments[e]]?0:t[this.arguments[e]];return t.cx=this.cx,t.cy=this.cy,this._undo=new(M[l(this.method)])(t,!0).at(1),this}}}),M.Translate=M.invent({parent:M.Matrix,inherit:M.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["transformedX","transformedY"],method:"translate"}}),M.Rotate=M.invent({parent:M.Matrix,inherit:M.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["rotation","cx","cy"],method:"rotate",at:function(t){var e=(new M.Matrix).rotate((new M.Number).morph(this.rotation-(this._undo?this._undo.rotation:0)).at(t),this.cx,this.cy);return this.inversed?e.inverse():e},undo:function(t){return this._undo=t,this}}}),M.Scale=M.invent({parent:M.Matrix,inherit:M.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["scaleX","scaleY","cx","cy"],method:"scale"}}),M.Skew=M.invent({parent:M.Matrix,inherit:M.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["skewX","skewY","cx","cy"],method:"skew"}}),M.extend(M.Element,{css:function(t,e){var n,i,r={};if(0===arguments.length)return this.node.style.cssText.split(/\s*;\s*/).filter(function(t){return!!t.length}).forEach(function(t){n=t.split(/\s*:\s*/),r[n[0]]=n[1]}),r;if(arguments.length<2){if(Array.isArray(t)){for(i=t.length;i--;)r[u(t[i])]=this.node.style[u(t[i])];return r}if("string"==typeof t)return this.node.style[u(t)];if("object"==typeof t)for(i in t)this.node.style[u(i)]=null==t[i]||M.regex.isBlank.test(t[i])?"":t[i]}return 2===arguments.length&&(this.node.style[u(t)]=null==e||M.regex.isBlank.test(e)?"":e),this}}),M.Parent=M.invent({create:function(t){this.constructor(t)},inherit:M.Element,extend:{children:function(){return M.utils.map(this.node.children,function(t){return M.adopt(t)})},add:function(t,e){return t=n(t),null==e?this.node.appendChild(t.node):t.node!==this.node.children[e]&&this.node.insertBefore(t.node,this.node.children[e]),this},put:function(t,e){return this.add(t,e),t.instance||t},has:function(t){return this.index(t)>=0},index:function(t){return[].slice.call(this.node.children).indexOf(t.node)},get:function(t){return M.adopt(this.node.children[t])},first:function(){return this.get(0)},last:function(){return this.get(this.node.children.length-1)},each:function(t,e){var n,i,r=this.children();for(n=0,i=r.length;n<i;n++)r[n]instanceof M.Element&&t.apply(r[n],[n,r]),e&&r[n]instanceof M.Parent&&r[n].each(t,e);return this},removeElement:function(t){return this.node.removeChild(t.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return delete this._defs,this}}}),M.extend(M.Parent,{flatten:function(t){return this instanceof M.Defs?this:(t=t||(this instanceof M.Doc?this:this.parent(M.Parent)),this.each(function(){return this instanceof M.Defs?this:this instanceof M.Parent?this.flatten(t):this.toParent(t)}),this.node.firstElementChild||this.remove(),this)}}),M.Container=M.invent({create:function(t){this.constructor(t)},inherit:M.Parent}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach(function(t){M.Element.prototype[t]=function(e){return M.on(this,t,e),this}}),M.listeners=[],M.handlerMap=[],M.listenerId=0,M.on=function(t,e,n,i,r){e.split(M.regex.delimiter).forEach(function(e){var s=n.bind(i||t),a=t instanceof M.Element?t.node:t,o=(M.handlerMap.indexOf(a)+1||M.handlerMap.push(a))-1,h=e.split(".")[0],u=e.split(".")[1]||"*";M.listeners[o]=M.listeners[o]||{},M.listeners[o][h]=M.listeners[o][h]||{},M.listeners[o][h][u]=M.listeners[o][h][u]||{},n._svgjsListenerId||(n._svgjsListenerId=++M.listenerId),M.listeners[o][h][u][n._svgjsListenerId]=s,a.addEventListener(h,s,r||!1)})},M.off=function(t,e,n){var i=M.handlerMap.indexOf(t),r=e&&e.split(".")[0],s=e&&e.split(".")[1],a="";if(-1!==i)if(n){if("function"==typeof n&&(n=n._svgjsListenerId),!n)return;M.listeners[i][r]&&M.listeners[i][r][s||"*"]&&(t.removeEventListener(r,M.listeners[i][r][s||"*"][n],!1),delete M.listeners[i][r][s||"*"][n])}else if(s&&r){if(M.listeners[i][r]&&M.listeners[i][r][s]){for(n in M.listeners[i][r][s])M.off(t,[r,s].join("."),n);delete M.listeners[i][r][s]}}else if(s)for(e in M.listeners[i])for(a in M.listeners[i][e])s===a&&M.off(t,[e,s].join("."));else if(r){if(M.listeners[i][r]){for(a in M.listeners[i][r])M.off(t,[r,a].join("."));delete M.listeners[i][r]}}else{for(e in M.listeners[i])M.off(t,e);delete M.listeners[i],delete M.handlerMap[i]}},M.extend(M.Element,{on:function(t,e,n,i){return M.on(this,t,e,n,i),this},off:function(t,e){return M.off(this.node,t,e),this},fire:function(e,n){return e instanceof t.Event?this.node.dispatchEvent(e):this.node.dispatchEvent(e=new t.CustomEvent(e,{detail:n,cancelable:!0})),this._event=e,this},event:function(){return this._event}}),M.Defs=M.invent({create:"defs",inherit:M.Container}),M.G=M.invent({create:"g",inherit:M.Container,extend:{x:function(t){return null==t?this.transform("x"):this.transform({x:t-this.x()},!0)},y:function(t){return null==t?this.transform("y"):this.transform({y:t-this.y()},!0)},cx:function(t){return null==t?this.gbox().cx:this.x(t-this.gbox().width/2)},cy:function(t){return null==t?this.gbox().cy:this.y(t-this.gbox().height/2)},gbox:function(){var t=this.bbox(),e=this.transform();return t.x+=e.x,t.x2+=e.x,t.cx+=e.x,t.y+=e.y,t.y2+=e.y,t.cy+=e.y,t}},construct:{group:function(){return this.put(new M.G)}}}),M.extend(M.Element,{siblings:function(){return this.parent().children()},position:function(){return this.parent().index(this)},next:function(){return this.siblings()[this.position()+1]},prev:function(){return this.siblings()[this.position()-1]},forward:function(){var t=this.position()+1,e=this.parent();return e.removeElement(this).add(this,t),e instanceof M.Doc&&e.node.appendChild(e.defs().node),this},backward:function(){var t=this.position();return t>0&&this.parent().removeElement(this).add(this,t-1),this},front:function(){var t=this.parent();return t.node.appendChild(this.node),t instanceof M.Doc&&t.node.appendChild(t.defs().node),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}}),M.Mask=M.invent({create:"mask",inherit:M.Container,extend:{remove:function(){return this.targets().forEach(function(t){t.unmask()}),M.Element.prototype.remove.call(this)},targets:function(){return M.select('svg [mask*="'+this.id()+'"]')}},construct:{mask:function(){return this.defs().put(new M.Mask)}}}),M.extend(M.Element,{maskWith:function(t){var e=t instanceof M.Mask?t:this.parent().mask().add(t);return this.attr("mask",'url("#'+e.id()+'")')},unmask:function(){return this.attr("mask",null)},masker:function(){return this.reference("mask")}}),M.ClipPath=M.invent({create:"clipPath",inherit:M.Container,extend:{remove:function(){return this.targets().forEach(function(t){t.unclip()}),M.Element.prototype.remove.call(this)},targets:function(){return M.select('svg [clip-path*="'+this.id()+'"]')}},construct:{clip:function(){return this.defs().put(new M.ClipPath)}}}),M.extend(M.Element,{clipWith:function(t){var e=t instanceof M.ClipPath?t:this.parent().clip().add(t);return this.attr("clip-path",'url("#'+e.id()+'")')},unclip:function(){return this.attr("clip-path",null)},clipper:function(){return this.reference("clip-path")}}),M.Gradient=M.invent({create:function(t){this.constructor("object"==typeof t?t:M.create(t+"Gradient"))},inherit:M.Container,extend:{stop:function(t,e,n){return this.put(new M.Stop).update(t,e,n)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},url:function(){return"url(#"+this.id()+")"},toString:function(){return this.url()},attr:function(t,e,n){return"transform"===t&&(t="gradientTransform"),M.Container.prototype.attr.call(this,t,e,n)}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),M.extend([M.Gradient,M.FX],{from:function(t,e){return"radialGradient"===(this._target||this).type?this.attr({fx:new M.Number(t),fy:new M.Number(e)}):this.attr({x1:new M.Number(t),y1:new M.Number(e)})},to:function(t,e){return"radialGradient"===(this._target||this).type?this.attr({cx:new M.Number(t),cy:new M.Number(e)}):this.attr({x2:new M.Number(t),y2:new M.Number(e)})}}),M.extend(M.Defs,{gradient:function(t,e){return this.put(new M.Gradient(t)).update(e)}}),M.Stop=M.invent({create:"stop",inherit:M.Element,extend:{update:function(t){return("number"==typeof t||t instanceof M.Number)&&(t={offset:arguments[0],color:arguments[1],opacity:arguments[2]}),null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new M.Number(t.offset)),this}}}),M.Pattern=M.invent({create:"pattern",inherit:M.Container,extend:{url:function(){return"url(#"+this.id()+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.url()},attr:function(t,e,n){return"transform"===t&&(t="patternTransform"),M.Container.prototype.attr.call(this,t,e,n)}},construct:{pattern:function(t,e,n){return this.defs().pattern(t,e,n)}}}),M.extend(M.Defs,{pattern:function(t,e,n){return this.put(new M.Pattern).update(n).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),M.Doc=M.invent({create:function(t){this.constructor(t||M.create("svg")),this.namespace().defs()},inherit:M.Container,extend:{namespace:function(){return this.attr({xmlns:M.ns,version:"1.1"}).attr("xmlns:xlink",M.xlink,M.xmlns).attr("xmlns:svgjs",M.svgjs,M.xmlns)},defs:function(){return M.adopt(this.node.getElementsByTagName("defs")[0])||this.put(new M.Defs)},parent:function(){return"#document"===this.node.parentNode.nodeName?null:this.node.parentNode},remove:function(){return this.parent()&&this.parent().removeChild(this.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this},toNested:function(){var t=M.create("svg");return this.node.instance=null,t.appendChild(this.node),M.adopt(this.node)}}}),M.Shape=M.invent({create:function(t){this.constructor(t)},inherit:M.Element}),M.Bare=M.invent({create:function(t,e){if(this.constructor(M.create(t)),e)for(var n in e.prototype)"function"==typeof e.prototype[n]&&(this[n]=e.prototype[n])},inherit:M.Element,extend:{words:function(t){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this.node.appendChild(e.createTextNode(t)),this}}}),M.extend(M.Parent,{element:function(t,e){return this.put(new M.Bare(t,e))}}),M.Symbol=M.invent({create:"symbol",inherit:M.Container,construct:{symbol:function(){return this.put(new M.Symbol)}}}),M.Use=M.invent({create:"use",inherit:M.Shape,extend:{element:function(t,e){return this.attr("href",(e||"")+"#"+t,M.xlink)}},construct:{use:function(t,e){return this.put(new M.Use).element(t,e)}}}),M.Rect=M.invent({create:"rect",inherit:M.Shape,construct:{rect:function(t,e){return this.put(new M.Rect).size(t,e)}}}),M.Circle=M.invent({create:"circle",inherit:M.Shape,construct:{circle:function(t){return this.put(new M.Circle).rx(new M.Number(t).divide(2)).move(0,0)}}}),M.extend([M.Circle,M.FX],{rx:function(t){return this.attr("r",t)},ry:function(t){return this.rx(t)}}),M.Ellipse=M.invent({create:"ellipse",inherit:M.Shape,construct:{ellipse:function(t,e){return this.put(new M.Ellipse).size(t,e).move(0,0)}}}),M.extend([M.Ellipse,M.Rect,M.FX],{rx:function(t){return this.attr("rx",t)},ry:function(t){return this.attr("ry",t)}}),M.extend([M.Circle,M.Ellipse],{x:function(t){return null==t?this.cx()-this.rx():this.cx(t+this.rx())},y:function(t){return null==t?this.cy()-this.ry():this.cy(t+this.ry())},cx:function(t){return null==t?this.attr("cx"):this.attr("cx",t)},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",t)},width:function(t){return null==t?2*this.rx():this.rx(new M.Number(t).divide(2))},height:function(t){return null==t?2*this.ry():this.ry(new M.Number(t).divide(2))},size:function(t,e){var n=d(this,t,e);return this.rx(new M.Number(n.width).divide(2)).ry(new M.Number(n.height).divide(2))}}),M.Line=M.invent({create:"line",inherit:M.Shape,extend:{array:function(){return new M.PointArray([[this.attr("x1"),this.attr("y1")],[this.attr("x2"),this.attr("y2")]])},plot:function(t,e,n,i){return null==t?this.array():(t=void 0!==e?{x1:t,y1:e,x2:n,y2:i}:new M.PointArray(t).toLine(),this.attr(t))},move:function(t,e){return this.attr(this.array().move(t,e).toLine())},size:function(t,e){var n=d(this,t,e);return this.attr(this.array().size(n.width,n.height).toLine())}},construct:{line:function(t,e,n,i){return M.Line.prototype.plot.apply(this.put(new M.Line),null!=t?[t,e,n,i]:[0,0,0,0])}}}),M.Polyline=M.invent({create:"polyline",inherit:M.Shape,construct:{polyline:function(t){return this.put(new M.Polyline).plot(t||new M.PointArray)}}}),M.Polygon=M.invent({create:"polygon",inherit:M.Shape,construct:{polygon:function(t){return this.put(new M.Polygon).plot(t||new M.PointArray)}}}),M.extend([M.Polyline,M.Polygon],{array:function(){return this._array||(this._array=new M.PointArray(this.attr("points")))},plot:function(t){return null==t?this.array():this.clear().attr("points","string"==typeof t?t:this._array=new M.PointArray(t))},clear:function(){return delete this._array,this},move:function(t,e){return this.attr("points",this.array().move(t,e))},size:function(t,e){var n=d(this,t,e);return this.attr("points",this.array().size(n.width,n.height))}}),M.extend([M.Line,M.Polyline,M.Polygon],{MorphArray:M.PointArray,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)}}),M.Path=M.invent({create:"path",inherit:M.Shape,extend:{MorphArray:M.PathArray,array:function(){return this._array||(this._array=new M.PathArray(this.attr("d")))},plot:function(t){return null==t?this.array():this.clear().attr("d","string"==typeof t?t:this._array=new M.PathArray(t))},clear:function(){return delete this._array,this},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 n=d(this,t,e);return this.attr("d",this.array().size(n.width,n.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 M.Path).plot(t||new M.PathArray)}}}),M.Image=M.invent({create:"image",inherit:M.Shape,extend:{load:function(e,n){if(!e)return this;var i=new t.Image;return M.on(i,"load",function(t){var r=this.parent(M.Pattern);0===this.width()&&0===this.height()&&this.size(i.width,i.height),r instanceof M.Pattern&&0===r.width()&&0===r.height()&&r.size(this.width(),this.height()),"function"==typeof n&&n.call(this,{width:i.width,height:i.height,ratio:i.width/i.height,url:e})},this),M.on(i,"load error",function(){M.off(i)}),this.attr("href",i.src=e,M.xlink)}},construct:{image:function(t,e){return this.put(new M.Image).size(0,0).load(t,e)}}}),M.Text=M.invent({create:function(t){this.constructor(t||M.create("text")),this.dom.leading=new M.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",M.defaults.attrs["font-family"])},inherit:M.Parent,extend:{x:function(t){return null==t?this.attr("x"):this.attr("x",t)},y:function(t){var e=this.attr("y"),n="number"==typeof e?e-this.bbox().y:0;return null==t?"number"==typeof e?e-n:e:this.attr("y","number"==typeof t?t+n:t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)},text:function(t){if(void 0===t){var e=this.node.childNodes,n=0;t="";for(var i=0,r=e.length;i<r;++i)"textPath"!==e[i].nodeName?(i!==n&&3!==e[i].nodeType&&!0===M.adopt(e[i]).dom.newLined&&(t+="\n"),t+=e[i].textContent):0===i&&(n=1);return t}if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{t=t.split("\n");for(var s=0,a=t.length;s<a;s++)this.tspan(t[s]).newLine()}return this.build(!1).rebuild()},size:function(t){return this.attr("font-size",t).rebuild()},leading:function(t){return null==t?this.dom.leading:(this.dom.leading=new M.Number(t),this.rebuild())},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this,n=0,i=this.dom.leading*new M.Number(this.attr("font-size"));this.each(function(){this.dom.newLined&&(this.attr("x",e.attr("x")),"\n"===this.text()?n+=i:(this.attr("dy",i+n),n=0))}),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this},setData:function(t){return this.dom=t,this.dom.leading=new M.Number(t.leading||1.3),this}},construct:{text:function(t){return this.put(new M.Text).text(t)},plain:function(t){return this.put(new M.Text).plain(t)}}}),M.Tspan=M.invent({create:"tspan",inherit:M.Parent,extend:{text:function(t){return null==t?this.node.textContent+(this.dom.newLined?"\n":""):("function"==typeof t?t.call(this,this):this.plain(t),this)},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.parent(M.Text);return this.dom.newLined=!0,this.dy(t.dom.leading*t.attr("font-size")).attr("x",t.x())}}}),M.extend([M.Text,M.Tspan],{plain:function(t){return!1===this._build&&this.clear(),this.node.appendChild(e.createTextNode(t)),this},tspan:function(t){var e=new M.Tspan;return this._build||this.clear(),this.node.appendChild(e.node),e.text(t)},length:function(){return this.node.getComputedTextLength()}}),M.TextPath=M.invent({create:"textPath",inherit:M.Text,parent:M.Parent,extend:{MorphArray:M.PathArray,array:function(){var t=this.track();return t?t.array():null},plot:function(t){var e=this.track(),n=null;return e&&(n=e.plot(t)),null==t?n:this},track:function(){return this.reference("href")}},construct:{textPath:function(t,e){return this.defs().path(e).text(t).addTo(this)}}}),M.extend([M.Text],{path:function(t){var e=new M.TextPath;return t instanceof M.Path||(t=this.doc().defs().path(t)),e.attr("href","#"+t,M.xlink),this.put(e)},textPath:function(){return this.select("textPath")}}),M.extend([M.Path],{text:function(t){if(t instanceof M.Text){var e=t.text();return t.clear().path(this).text(e)}return this.parent().put(new M.Text).path(this).text(t)}}),M.Nested=M.invent({create:"svg",inherit:M.Container,construct:{nested:function(){return this.put(new M.Nested)}}}),M.A=M.invent({create:"a",inherit:M.Container,extend:{to:function(t){return this.attr("href",t,M.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new M.A).to(t)}}}),M.extend(M.Element,{linkTo:function(t){var e=new M.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent().put(e).put(this)}}),M.Marker=M.invent({create:"marker",inherit:M.Container,extend:{width:function(t){return this.attr("markerWidth",t)},height:function(t){return this.attr("markerHeight",t)},ref:function(t,e){return this.attr("refX",t).attr("refY",e)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return"url(#"+this.id()+")"}},construct:{marker:function(t,e,n){return this.defs().marker(t,e,n)}}}),M.extend(M.Defs,{marker:function(t,e,n){return this.put(new M.Marker).size(t,e).ref(t/2,e/2).viewbox(0,0,t,e).attr("orient","auto").update(n)}}),M.extend([M.Line,M.Polyline,M.Polygon,M.Path],{marker:function(t,e,n,i){var r=["marker"];return"all"!==t&&r.push(t),r=r.join("-"),t=arguments[1]instanceof M.Marker?arguments[1]:this.doc().marker(e,n,i),this.attr(r,t)}});var k={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(t,e){return"color"===e?t:t+"-"+e}};["fill","stroke"].forEach(function(t){var e,n={};n[t]=function(n){if(void 0===n)return this;if("string"==typeof n||M.Color.isRgb(n)||n&&"function"==typeof n.fill)this.attr(t,n);else for(e=k[t].length-1;e>=0;e--)null!=n[k[t][e]]&&this.attr(k.prefix(t,k[t][e]),n[k[t][e]]);return this},M.extend([M.Element,M.FX],n)}),M.extend([M.Element,M.FX],{rotate:function(t,e,n){return this.transform({rotation:t,cx:e,cy:n})},skew:function(t,e,n,i){return 1===arguments.length||3===arguments.length?this.transform({skew:t,cx:e,cy:n}):this.transform({skewX:t,skewY:e,cx:n,cy:i})},scale:function(t,e,n,i){return 1===arguments.length||3===arguments.length?this.transform({scale:t,cx:e,cy:n}):this.transform({scaleX:t,scaleY:e,cx:n,cy:i})},translate:function(t,e){return this.transform({x:t,y:e})},flip:function(t,e){return e="number"==typeof t?t:e,this.transform({flip:t||"both",offset:e})},matrix:function(t){return this.attr("transform",new M.Matrix(6===arguments.length?[].slice.call(arguments):t))},opacity:function(t){return this.attr("opacity",t)},dx:function(t){return this.x(new M.Number(t).plus(this instanceof M.FX?0:this.x()),!0)},dy:function(t){return this.y(new M.Number(t).plus(this instanceof M.FX?0:this.y()),!0)},dmove:function(t,e){return this.dx(t).dy(e)}}),M.extend([M.Rect,M.Ellipse,M.Circle,M.Gradient,M.FX],{radius:function(t,e){var n=(this._target||this).type;return"radialGradient"===n||"radialGradient"===n?this.attr("r",new M.Number(t)):this.rx(t).ry(null==e?t:e)}}),M.extend(M.Path,{length:function(){return this.node.getTotalLength()},pointAt:function(t){return new M.Point(this.node.getPointAtLength(t))}}),M.extend([M.Parent,M.Text,M.Tspan,M.FX],{font:function(t,e){if("object"==typeof t)for(e in t)this.font(e,t[e]);return"leading"===t?this.leading(e):"anchor"===t?this.attr("text-anchor",e):"size"===t||"family"===t||"weight"===t||"stretch"===t||"variant"===t||"style"===t?this.attr("font-"+t,e):this.attr(t,e)}}),M.extend(M.Element,{data:function(t,e,n){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+t))}catch(e){return this.attr("data-"+t)}else this.attr("data-"+t,null===e?null:!0===n||"string"==typeof e||"number"==typeof e?e:JSON.stringify(e));return this}}),M.extend(M.Element,{remember:function(t,e){if("object"==typeof arguments[0])for(var n in t)this.remember(n,t[n]);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={})}}),M.get=function(t){var n=e.getElementById(b(t)||t);return M.adopt(n)},M.select=function(t,n){return M.utils.map((n||e).querySelectorAll(t),function(t){return M.adopt(t)})},M.$$=function(t,n){return M.utils.map((n||e).querySelectorAll(t),function(t){return M.adopt(t)})},M.$=function(t,n){return M.adopt((n||e).querySelector(t))},M.extend(M.Parent,{select:function(t){return M.select(t,this.node)}});var S="abcdef".split("");return M.Box=M.invent({create:function(t){var e=[0,0,0,0];t="string"==typeof t?t.split(M.regex.delimiter).map(parseFloat):Array.isArray(t)?t:"object"==typeof t?[null!=t.left?t.left:t.x,null!=t.top?t.top:t.y,t.width,t.height]:4===arguments.length?[].slice.call(arguments):e,this.x=t[0],this.y=t[1],this.width=t[2],this.height=t[3],w(this)},extend:{merge:function(t){var e=Math.min(this.x,t.x),n=Math.min(this.y,t.y);return new M.Box(e,n,Math.max(this.x+this.width,t.x+t.width)-e,Math.max(this.y+this.height,t.y+t.height)-n)},transform:function(t){var e=1/0,n=-1/0,i=1/0,r=-1/0;return[new M.Point(this.x,this.y),new M.Point(this.x2,this.y),new M.Point(this.x,this.y2),new M.Point(this.x2,this.y2)].forEach(function(s){s=s.transform(t),e=Math.min(e,s.x),n=Math.max(n,s.x),i=Math.min(i,s.y),r=Math.max(r,s.y)}),new M.Box(e,i,n-e,r-i)},addOffset:function(){return this.x+=t.pageXOffset,this.y+=t.pageYOffset,this},toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height},morph:function(t,e,n,i){return this.destination=new M.Box(t,e,n,i),this},at:function(t){return this.destination?new M.Box(this.x+(this.destination.x-this.x)*t,this.y+(this.destination.y-this.y)*t,this.width+(this.destination.width-this.width)*t,this.height+(this.destination.height-this.height)*t):this}},parent:M.Element,construct:{bbox:function(){var t;try{if(t=this.node.getBBox(),i(t)&&!r(this.node))throw new Exception("Element not in the dom")}catch(n){try{var e=this.clone(M.parser().svg).show();t=e.node.getBBox(),e.remove()}catch(t){console.warn("Getting a bounding box of this element is not possible")}}return new M.Box(t)},rbox:function(t){try{var e=new M.Box(this.node.getBoundingClientRect());return t?e.transform(t.screenCTM().inverse()):e.addOffset()}catch(t){return new M.Box}}}}),M.extend([M.Doc,M.Nested,M.Symbol,M.Image,M.Pattern,M.Marker,M.ForeignObject,M.View],{viewbox:function(t,e,n,i){return null==t?new M.Box(this.attr("viewBox")):this.attr("viewBox",new M.Box(t,e,n,i))}}),M.parser=function(){var t;return M.parser.nodes.svg.node.parentNode||(t=e.body||e.documentElement,M.parser.nodes.svg.addTo(t)),M.parser.nodes},M.parser.nodes={svg:(new M.Nested).size(2,0).css({opacity:0,position:"absolute",left:"-100%",top:"-100%",overflow:"hidden"})},M.parser.nodes.path=M.parser.nodes.svg.path().node,M}); \ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index e7618a0..545a27f 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,91 +1,89 @@
-var del = require('del')
- , gulp = require('gulp')
- , chmod = require('gulp-chmod')
- , concat = require('gulp-concat')
- , header = require('gulp-header')
- , rename = require('gulp-rename')
- , size = require('gulp-size')
- , trim = require('gulp-trimlines')
- , uglify = require('gulp-uglify')
- , wrapUmd = require('gulp-wrap')
- , request = require('request')
- , fs = require('fs')
- , pkg = require('./package.json')
+var del = require('del'),
+ gulp = require('gulp'),
+ chmod = require('gulp-chmod'),
+ concat = require('gulp-concat'),
+ header = require('gulp-header'),
+ rename = require('gulp-rename'),
+ size = require('gulp-size'),
+ trim = require('gulp-trimlines'),
+ uglify = require('gulp-uglify'),
+ wrapUmd = require('gulp-wrap'),
+ pkg = require('./package.json'),
+ standard = require('gulp-standard')
-
-var headerLong = ['/*!'
- , '* <%= pkg.name %> - <%= pkg.description %>'
- , '* @version <%= pkg.version %>'
- , '* <%= pkg.homepage %>'
- , '*'
- , '* @copyright <%= pkg.author %>'
- , '* @license <%= pkg.license %>'
- , '*'
- , '* BUILT: <%= pkg.buildDate %>'
- , '*/;'
- , ''].join('\n')
+var headerLong = ['/*!',
+ '* <%= pkg.name %> - <%= pkg.description %>',
+ '* @version <%= pkg.version %>',
+ '* <%= pkg.homepage %>',
+ '*',
+ '* @copyright <%= pkg.author %>',
+ '* @license <%= pkg.license %>',
+ '*',
+ '* BUILT: <%= pkg.buildDate %>',
+ '*/;',
+ ''].join('\n')
var headerShort = '/*! <%= pkg.name %> v<%= pkg.version %> <%= pkg.license %>*/;'
// all files in the right order (currently we don't use any dependency management system)
var parts = [
- 'src/svg.js'
-, 'src/regex.js'
-, 'src/utilities.js'
-, 'src/default.js'
-, 'src/color.js'
-, 'src/array.js'
-, 'src/pointarray.js'
-, 'src/patharray.js'
-, 'src/number.js'
-, 'src/HtmlNode.js'
-, 'src/element.js'
-, 'src/fx.js'
-, 'src/matrix.js'
-, 'src/point.js'
-, 'src/attr.js'
-, 'src/transform.js'
-, 'src/css.js'
-, 'src/parent.js'
-, 'src/flatten.js'
-, 'src/container.js'
-, 'src/event.js'
-, 'src/defs.js'
-, 'src/group.js'
-, 'src/arrange.js'
-, 'src/mask.js'
-, 'src/clip.js'
-, 'src/gradient.js'
-, 'src/pattern.js'
-, 'src/doc.js'
-, 'src/shape.js'
-, 'src/bare.js'
-, 'src/symbol.js'
-, 'src/use.js'
-, 'src/rect.js'
-, 'src/ellipse.js'
-, 'src/line.js'
-, 'src/poly.js'
-, 'src/pointed.js'
-, 'src/path.js'
-, 'src/image.js'
-, 'src/text.js'
-, 'src/textpath.js'
-, 'src/nested.js'
-, 'src/hyperlink.js'
-, 'src/marker.js'
-, 'src/sugar.js'
-, 'src/set.js'
-, 'src/data.js'
-, 'src/memory.js'
-, 'src/selector.js'
-, 'src/helpers.js'
-, 'src/polyfill.js'
-, 'src/boxes.js'
-, 'src/parser.js'
+ 'src/svg.js',
+ 'src/regex.js',
+ 'src/utilities.js',
+ 'src/default.js',
+ 'src/color.js',
+ 'src/array.js',
+ 'src/pointarray.js',
+ 'src/patharray.js',
+ 'src/number.js',
+ 'src/HtmlNode.js',
+ 'src/element.js',
+ 'src/fx.js',
+ 'src/matrix.js',
+ 'src/point.js',
+ 'src/attr.js',
+ 'src/transform.js',
+ 'src/css.js',
+ 'src/parent.js',
+ 'src/flatten.js',
+ 'src/container.js',
+ 'src/event.js',
+ 'src/defs.js',
+ 'src/group.js',
+ 'src/arrange.js',
+ 'src/mask.js',
+ 'src/clip.js',
+ 'src/gradient.js',
+ 'src/pattern.js',
+ 'src/doc.js',
+ 'src/shape.js',
+ 'src/bare.js',
+ 'src/symbol.js',
+ 'src/use.js',
+ 'src/rect.js',
+ 'src/ellipse.js',
+ 'src/line.js',
+ 'src/poly.js',
+ 'src/pointed.js',
+ 'src/path.js',
+ 'src/image.js',
+ 'src/text.js',
+ 'src/textpath.js',
+ 'src/nested.js',
+ 'src/hyperlink.js',
+ 'src/marker.js',
+ 'src/sugar.js',
+ 'src/set.js',
+ 'src/data.js',
+ 'src/memory.js',
+ 'src/selector.js',
+ 'src/helpers.js',
+ 'src/polyfill.js',
+ 'src/boxes.js',
+ 'src/parser.js'
]
-gulp.task('clean', function() {
+gulp.task('clean', function () {
return del([ 'dist/*' ])
})
@@ -94,12 +92,18 @@ gulp.task('clean', function() {
* wrap the whole thing in a UMD wrapper (@see https://github.com/umdjs/umd)
* add the license information to the header plus the build time stamp‏
*/
-gulp.task('unify', ['clean'], function() {
+gulp.task('unify', ['clean'], function () {
pkg.buildDate = Date()
return gulp.src(parts)
+ .pipe(standard())
+ .pipe(standard.reporter('default', {
+ showRuleNames: true,
+ breakOnError: true,
+ quiet: true
+ }))
.pipe(concat('svg.js', { newLine: '\n' }))
// wrap the whole thing in an immediate function call
- .pipe(wrapUmd({ src: 'src/umd.js'}))
+ .pipe(wrapUmd({src: 'src/umd.js'}))
.pipe(header(headerLong, { pkg: pkg }))
.pipe(trim({ leading: false }))
.pipe(chmod(0o644))
@@ -112,10 +116,10 @@ gulp.task('unify', ['clean'], function() {
* add the license info
* show the gzipped file size
*/
-gulp.task('minify', ['unify'], function() {
+gulp.task('minify', ['unify'], function () {
return gulp.src('dist/svg.js')
.pipe(uglify())
- .pipe(rename({ suffix:'.min' }))
+ .pipe(rename({ suffix: '.min' }))
.pipe(size({ showFiles: true, title: 'Minified' }))
.pipe(header(headerShort, { pkg: pkg }))
.pipe(chmod(0o644))
@@ -123,5 +127,4 @@ gulp.task('minify', ['unify'], function() {
.pipe(size({ showFiles: true, gzip: true, title: 'Gzipped' }))
})
-
-gulp.task('default', ['clean', 'unify', 'minify']) \ No newline at end of file
+gulp.task('default', ['clean', 'unify', 'minify'])
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..96d4bac
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,9169 @@
+{
+ "name": "svg.js",
+ "version": "3.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
+ "dev": true
+ },
+ "accepts": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
+ "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
+ "dev": true,
+ "requires": {
+ "mime-types": "2.1.18",
+ "negotiator": "0.6.1"
+ }
+ },
+ "acorn": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz",
+ "integrity": "sha512-XLmq3H/BVvW6/GbxKryGxWORz1ebilSsUDlyC27bXhWGWAZWkGwS6FLHjOlwFXNFoWFQEO/Df4u0YYd0K3BQgQ==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+ "dev": true,
+ "requires": {
+ "acorn": "3.3.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+ "dev": true
+ }
+ }
+ },
+ "after": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+ "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
+ "dev": true
+ },
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "dev": true,
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ },
+ "ajv-keywords": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
+ "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
+ "dev": true
+ },
+ "align-text": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2",
+ "longest": "1.0.1",
+ "repeat-string": "1.6.1"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "dev": true
+ },
+ "ansi-colors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+ "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+ "dev": true,
+ "requires": {
+ "ansi-wrap": "0.1.0"
+ }
+ },
+ "ansi-escapes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+ "dev": true
+ },
+ "ansi-gray": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+ "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
+ "dev": true,
+ "requires": {
+ "ansi-wrap": "0.1.0"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "ansi-wrap": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+ "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+ "dev": true,
+ "requires": {
+ "micromatch": "2.3.11",
+ "normalize-path": "2.1.1"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.1.0"
+ }
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+ "dev": true
+ },
+ "braces": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+ "dev": true,
+ "requires": {
+ "expand-range": "1.8.2",
+ "preserve": "0.2.0",
+ "repeat-element": "1.1.2"
+ }
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+ "dev": true,
+ "requires": {
+ "is-posix-bracket": "0.1.1"
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+ "dev": true,
+ "requires": {
+ "arr-diff": "2.0.0",
+ "array-unique": "0.2.1",
+ "braces": "1.8.5",
+ "expand-brackets": "0.1.5",
+ "extglob": "0.3.2",
+ "filename-regex": "2.0.1",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1",
+ "kind-of": "3.2.2",
+ "normalize-path": "2.1.1",
+ "object.omit": "2.0.1",
+ "parse-glob": "3.0.4",
+ "regex-cache": "0.4.4"
+ }
+ }
+ }
+ },
+ "app-root-path": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz",
+ "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=",
+ "dev": true
+ },
+ "archy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-differ": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
+ "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
+ "dev": true
+ },
+ "array-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+ "dev": true
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+ "dev": true
+ },
+ "array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "1.0.3"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "array.prototype.find": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz",
+ "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=",
+ "dev": true,
+ "requires": {
+ "define-properties": "1.1.2",
+ "es-abstract": "1.10.0"
+ }
+ },
+ "arraybuffer.slice": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz",
+ "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=",
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+ "dev": true
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
+ "ast-transform": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/ast-transform/-/ast-transform-0.0.0.tgz",
+ "integrity": "sha1-dJRAWIh9goPhidlUYAlHvJj+AGI=",
+ "dev": true,
+ "requires": {
+ "escodegen": "1.2.0",
+ "esprima": "1.0.4",
+ "through": "2.3.8"
+ },
+ "dependencies": {
+ "escodegen": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.2.0.tgz",
+ "integrity": "sha1-Cd55Z3kcyVi3+Jot220jRRrzJ+E=",
+ "dev": true,
+ "requires": {
+ "esprima": "1.0.4",
+ "estraverse": "1.5.1",
+ "esutils": "1.0.0",
+ "source-map": "0.1.43"
+ }
+ },
+ "esprima": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
+ "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
+ "dev": true
+ },
+ "estraverse": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz",
+ "integrity": "sha1-hno+jlip+EYYr7bC3bzZFrfLr3E=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz",
+ "integrity": "sha1-gVHTWOIMisx/t0XnRywAJf5JZXA=",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.1.43",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+ "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
+ }
+ },
+ "ast-types": {
+ "version": "0.7.8",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.7.8.tgz",
+ "integrity": "sha1-kC0uDWDQcb3NRtwRXhgJ7RHBOKk=",
+ "dev": true
+ },
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
+ "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+ "dev": true
+ },
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "esutils": "2.0.2",
+ "js-tokens": "3.0.2"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "dev": true,
+ "requires": {
+ "core-js": "2.5.3",
+ "regenerator-runtime": "0.11.1"
+ }
+ },
+ "backo2": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+ "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "1.0.1",
+ "class-utils": "0.3.6",
+ "component-emitter": "1.2.1",
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "mixin-deep": "1.3.1",
+ "pascalcase": "0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ }
+ }
+ },
+ "base64-arraybuffer": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+ "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+ "dev": true
+ },
+ "base64-js": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz",
+ "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==",
+ "dev": true
+ },
+ "base64id": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
+ "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "beeper": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz",
+ "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=",
+ "dev": true
+ },
+ "better-assert": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
+ "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
+ "dev": true,
+ "requires": {
+ "callsite": "1.0.0"
+ }
+ },
+ "binary-extensions": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+ "dev": true
+ },
+ "blob": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
+ "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=",
+ "dev": true
+ },
+ "bluebird": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+ "dev": true
+ },
+ "body-parser": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+ "dev": true,
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "1.0.4",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "on-finished": "2.3.0",
+ "qs": "6.5.1",
+ "raw-body": "2.3.2",
+ "type-is": "1.6.16"
+ },
+ "dependencies": {
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+ "dev": true
+ }
+ }
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz",
+ "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.1.0",
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "fill-range": "4.0.0",
+ "isobject": "3.0.1",
+ "kind-of": "6.0.2",
+ "repeat-element": "1.1.2",
+ "snapdragon": "0.8.1",
+ "snapdragon-node": "2.1.1",
+ "split-string": "3.1.0",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "brfs": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.4.4.tgz",
+ "integrity": "sha512-rX2qc9hkpLPiwdu1HkLY642rwwo3X6N+ZPyEPdNn3OUKV/B2BRP7dHdnkhGantOJLVoTluNYBi4VecHb2Kq2hw==",
+ "dev": true,
+ "requires": {
+ "quote-stream": "1.0.2",
+ "resolve": "1.5.0",
+ "static-module": "2.1.1",
+ "through2": "2.0.3"
+ }
+ },
+ "brotli": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.2.tgz",
+ "integrity": "sha1-UlqcrU/LqWR119OI9q7LE+7VL0Y=",
+ "dev": true,
+ "requires": {
+ "base64-js": "1.2.3"
+ }
+ },
+ "browser-resolve": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz",
+ "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=",
+ "dev": true,
+ "requires": {
+ "resolve": "1.1.7"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ }
+ }
+ },
+ "browserify-optional": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-optional/-/browserify-optional-1.0.1.tgz",
+ "integrity": "sha1-HhNyLP3g2F8SFnbCpyztUzoBiGk=",
+ "dev": true,
+ "requires": {
+ "ast-transform": "0.0.0",
+ "ast-types": "0.7.8",
+ "browser-resolve": "1.11.2"
+ }
+ },
+ "buffer-equal": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
+ "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=",
+ "dev": true
+ },
+ "bufferstreams": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-1.0.1.tgz",
+ "integrity": "sha1-z7GtlWjTujz+k1upq92VLeiKqyo=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.1.14"
+ }
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+ "dev": true
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "1.0.0",
+ "component-emitter": "1.2.1",
+ "get-value": "2.0.6",
+ "has-value": "1.0.0",
+ "isobject": "3.0.1",
+ "set-value": "2.0.0",
+ "to-object-path": "0.3.0",
+ "union-value": "1.0.0",
+ "unset-value": "1.0.0"
+ }
+ },
+ "caller-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+ "dev": true,
+ "requires": {
+ "callsites": "0.2.0"
+ }
+ },
+ "callsite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+ "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
+ "dev": true
+ },
+ "callsites": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "2.1.1",
+ "map-obj": "1.0.1"
+ }
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "dev": true
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+ "dev": true,
+ "requires": {
+ "align-text": "0.1.4",
+ "lazy-cache": "1.0.4"
+ },
+ "dependencies": {
+ "lazy-cache": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+ "dev": true
+ }
+ }
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "chokidar": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+ "dev": true,
+ "requires": {
+ "anymatch": "1.3.2",
+ "async-each": "1.0.1",
+ "fsevents": "1.1.3",
+ "glob-parent": "2.0.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "2.0.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.1.0"
+ },
+ "dependencies": {
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ }
+ }
+ },
+ "circular-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "dev": true
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "3.1.0",
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "static-extend": "0.1.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "cli-cursor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+ "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "1.0.1"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wrap-ansi": "2.1.0"
+ }
+ },
+ "clone": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
+ "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=",
+ "dev": true
+ },
+ "clone-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+ "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+ "dev": true
+ },
+ "clone-stats": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
+ "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=",
+ "dev": true
+ },
+ "cloneable-readable": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz",
+ "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "process-nextick-args": "1.0.7",
+ "through2": "2.0.3"
+ },
+ "dependencies": {
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ }
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "1.0.0",
+ "object-visit": "1.0.1"
+ }
+ },
+ "color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+ "dev": true
+ },
+ "combine-lists": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz",
+ "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=",
+ "dev": true,
+ "requires": {
+ "lodash": "4.17.5"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ }
+ }
+ },
+ "combined-stream": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
+ "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==",
+ "dev": true
+ },
+ "component-bind": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+ "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
+ "dev": true
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "component-inherit": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+ "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.4",
+ "typedarray": "0.0.6"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
+ "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "concat-with-sourcemaps": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.5.tgz",
+ "integrity": "sha512-YtnS0VEY+e2Khzsey/6mra9EoM6h/5gxaC0e3mcHpA5yfDxafhygytNmcJWodvUgyXzSiL5MSkPO6bQGgfliHw==",
+ "dev": true,
+ "requires": {
+ "source-map": "0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "connect": {
+ "version": "3.6.6",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
+ "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.0",
+ "parseurl": "1.3.2",
+ "utils-merge": "1.0.1"
+ }
+ },
+ "consolidate": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.14.5.tgz",
+ "integrity": "sha1-WiUEe8dvcwcmZ8jLUsmJiI9JTGM=",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.5.1"
+ }
+ },
+ "contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+ "dev": true
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "dev": true
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+ "dev": true
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "copy-props": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-1.6.0.tgz",
+ "integrity": "sha1-8DJLvumXcRAeezraES8xPDk9uO0=",
+ "dev": true,
+ "requires": {
+ "each-props": "1.3.1",
+ "is-plain-object": "2.0.4"
+ }
+ },
+ "core-js": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
+ "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "coveralls": {
+ "version": "2.13.3",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.3.tgz",
+ "integrity": "sha512-iiAmn+l1XqRwNLXhW8Rs5qHZRFMYp9ZIPjEOVRpC/c4so6Y/f4/lFi0FfR5B9cCqgyhkJ5cZmbvcVRfP8MHchw==",
+ "dev": true,
+ "requires": {
+ "js-yaml": "3.6.1",
+ "lcov-parse": "0.0.10",
+ "log-driver": "1.2.5",
+ "minimist": "1.2.0",
+ "request": "2.79.0"
+ },
+ "dependencies": {
+ "request": {
+ "version": "2.79.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "caseless": "0.11.0",
+ "combined-stream": "1.0.6",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.1.4",
+ "har-validator": "2.0.6",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.18",
+ "oauth-sign": "0.8.2",
+ "qs": "6.3.2",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.4.3",
+ "uuid": "3.2.1"
+ }
+ }
+ }
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1"
+ }
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "requires": {
+ "array-find-index": "1.0.2"
+ }
+ },
+ "custom-event": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
+ "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
+ "dev": true
+ },
+ "d": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "0.10.39"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "dateformat": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
+ "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "debug-log": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz",
+ "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=",
+ "dev": true
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
+ },
+ "deep-assign": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz",
+ "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=",
+ "dev": true,
+ "requires": {
+ "is-obj": "1.0.1"
+ }
+ },
+ "deep-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
+ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
+ "dev": true
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "defaults": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
+ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+ "dev": true,
+ "requires": {
+ "clone": "1.0.3"
+ }
+ },
+ "define-properties": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+ "dev": true,
+ "requires": {
+ "foreach": "2.0.5",
+ "object-keys": "1.0.11"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2",
+ "isobject": "3.0.1"
+ }
+ },
+ "deglob": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz",
+ "integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=",
+ "dev": true,
+ "requires": {
+ "find-root": "1.1.0",
+ "glob": "7.1.2",
+ "ignore": "3.3.7",
+ "pkg-config": "1.1.1",
+ "run-parallel": "1.1.7",
+ "uniq": "1.0.1"
+ }
+ },
+ "del": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+ "dev": true,
+ "requires": {
+ "globby": "5.0.0",
+ "is-path-cwd": "1.0.0",
+ "is-path-in-cwd": "1.0.0",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "rimraf": "2.6.2"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "deprecated": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz",
+ "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=",
+ "dev": true
+ },
+ "detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+ "dev": true
+ },
+ "dfa": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.1.0.tgz",
+ "integrity": "sha1-0wIYvRDQMPpCHfPrvIIoVGOjF4E=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "di": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
+ "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
+ "dev": true
+ },
+ "doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "requires": {
+ "esutils": "2.0.2"
+ }
+ },
+ "dom-serialize": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
+ "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
+ "dev": true,
+ "requires": {
+ "custom-event": "1.0.1",
+ "ent": "2.2.0",
+ "extend": "3.0.1",
+ "void-elements": "2.0.1"
+ }
+ },
+ "duplexer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+ "dev": true
+ },
+ "duplexer2": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
+ "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.1.14"
+ }
+ },
+ "each-props": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.1.tgz",
+ "integrity": "sha1-/BOPUeOid0KG1IWOAtbn3kYt4Vg=",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4",
+ "object.defaults": "1.1.0"
+ }
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+ "dev": true
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz",
+ "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=",
+ "dev": true,
+ "requires": {
+ "once": "1.3.3"
+ },
+ "dependencies": {
+ "once": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ }
+ }
+ },
+ "engine.io": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz",
+ "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=",
+ "dev": true,
+ "requires": {
+ "accepts": "1.3.3",
+ "base64id": "1.0.0",
+ "cookie": "0.3.1",
+ "debug": "2.3.3",
+ "engine.io-parser": "1.3.2",
+ "ws": "1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ }
+ }
+ },
+ "engine.io-client": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz",
+ "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=",
+ "dev": true,
+ "requires": {
+ "component-emitter": "1.2.1",
+ "component-inherit": "0.0.3",
+ "debug": "2.3.3",
+ "engine.io-parser": "1.3.2",
+ "has-cors": "1.1.0",
+ "indexof": "0.0.1",
+ "parsejson": "0.0.3",
+ "parseqs": "0.0.5",
+ "parseuri": "0.0.5",
+ "ws": "1.1.2",
+ "xmlhttprequest-ssl": "1.5.3",
+ "yeast": "0.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ }
+ }
+ },
+ "engine.io-parser": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz",
+ "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=",
+ "dev": true,
+ "requires": {
+ "after": "0.8.2",
+ "arraybuffer.slice": "0.0.6",
+ "base64-arraybuffer": "0.1.5",
+ "blob": "0.0.4",
+ "has-binary": "0.1.7",
+ "wtf-8": "1.0.0"
+ }
+ },
+ "ent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
+ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
+ "dev": true
+ },
+ "error-ex": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz",
+ "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "1.1.1",
+ "function-bind": "1.1.1",
+ "has": "1.0.1",
+ "is-callable": "1.1.3",
+ "is-regex": "1.0.4"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
+ "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
+ "dev": true,
+ "requires": {
+ "is-callable": "1.1.3",
+ "is-date-object": "1.0.1",
+ "is-symbol": "1.0.1"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.39",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.39.tgz",
+ "integrity": "sha512-AlaXZhPHl0po/uxMx1tyrlt1O86M6D5iVaDH8UgLfgek4kXTX6vzsRfJQWC2Ku+aG8pkw1XWzh9eTkwfVrsD5g==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.39",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "es6-map": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.39",
+ "es6-iterator": "2.0.3",
+ "es6-set": "0.1.5",
+ "es6-symbol": "3.1.1",
+ "event-emitter": "0.3.5"
+ }
+ },
+ "es6-promise": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
+ "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=",
+ "dev": true
+ },
+ "es6-set": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.39",
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.1",
+ "event-emitter": "0.3.5"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.39"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.39",
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "escodegen": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+ "dev": true,
+ "requires": {
+ "esprima": "2.7.3",
+ "estraverse": "1.9.3",
+ "esutils": "2.0.2",
+ "optionator": "0.8.2",
+ "source-map": "0.2.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+ "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
+ }
+ },
+ "escope": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+ "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
+ "dev": true,
+ "requires": {
+ "es6-map": "0.1.5",
+ "es6-weak-map": "2.0.2",
+ "esrecurse": "4.2.0",
+ "estraverse": "4.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ }
+ }
+ },
+ "eslint": {
+ "version": "3.18.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.18.0.tgz",
+ "integrity": "sha1-ZH6YXErnFQLSCsYsEJ9m1RBMiks=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "chalk": "1.1.3",
+ "concat-stream": "1.6.0",
+ "debug": "2.6.9",
+ "doctrine": "2.1.0",
+ "escope": "3.6.0",
+ "espree": "3.5.3",
+ "esquery": "1.0.0",
+ "estraverse": "4.2.0",
+ "esutils": "2.0.2",
+ "file-entry-cache": "2.0.0",
+ "glob": "7.1.2",
+ "globals": "9.18.0",
+ "ignore": "3.3.7",
+ "imurmurhash": "0.1.4",
+ "inquirer": "0.12.0",
+ "is-my-json-valid": "2.17.2",
+ "is-resolvable": "1.1.0",
+ "js-yaml": "3.6.1",
+ "json-stable-stringify": "1.0.1",
+ "levn": "0.3.0",
+ "lodash": "4.17.5",
+ "mkdirp": "0.5.1",
+ "natural-compare": "1.4.0",
+ "optionator": "0.8.2",
+ "path-is-inside": "1.0.2",
+ "pluralize": "1.2.1",
+ "progress": "1.1.8",
+ "require-uncached": "1.0.3",
+ "shelljs": "0.7.8",
+ "strip-bom": "3.0.0",
+ "strip-json-comments": "2.0.1",
+ "table": "3.8.3",
+ "text-table": "0.2.0",
+ "user-home": "2.0.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "user-home": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+ "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "1.0.2"
+ }
+ }
+ }
+ },
+ "eslint-config-standard": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-7.1.0.tgz",
+ "integrity": "sha1-R+dp6gc59bLVaTsaUBwhyWUPr88=",
+ "dev": true
+ },
+ "eslint-config-standard-jsx": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-3.3.0.tgz",
+ "integrity": "sha1-yrCAGhWjYL9j+suXqyL73YjYpeA=",
+ "dev": true
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz",
+ "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "object-assign": "4.1.1",
+ "resolve": "1.5.0"
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz",
+ "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "pkg-dir": "1.0.0"
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz",
+ "integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "1.1.1",
+ "contains-path": "0.1.0",
+ "debug": "2.6.9",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "0.2.3",
+ "eslint-module-utils": "2.1.1",
+ "has": "1.0.1",
+ "lodash.cond": "4.5.2",
+ "minimatch": "3.0.4",
+ "pkg-up": "1.0.0"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "2.0.2",
+ "isarray": "1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-node": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz",
+ "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==",
+ "dev": true,
+ "requires": {
+ "ignore": "3.3.7",
+ "minimatch": "3.0.4",
+ "object-assign": "4.1.1",
+ "resolve": "1.5.0",
+ "semver": "5.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-promise": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.4.2.tgz",
+ "integrity": "sha1-G+J5Pq/i0YtbEjuBNsJp+AT+cSI=",
+ "dev": true
+ },
+ "eslint-plugin-react": {
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.9.0.tgz",
+ "integrity": "sha1-VMLpkGt2+dEBQgML3DTp1oQKC7I=",
+ "dev": true,
+ "requires": {
+ "array.prototype.find": "2.0.4",
+ "doctrine": "1.5.0",
+ "jsx-ast-utils": "1.4.1"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "2.0.2",
+ "isarray": "1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-standard": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-2.0.1.tgz",
+ "integrity": "sha1-NYlpn/nJF/LCX3apFmh/ZBw2n/M=",
+ "dev": true
+ },
+ "espree": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.3.tgz",
+ "integrity": "sha512-Zy3tAJDORxQZLl2baguiRU1syPERAIg0L+JB2MWorORgTu/CplzvxS9WWA7Xh4+Q+eOQihNs/1o1Xep8cvCxWQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "5.4.1",
+ "acorn-jsx": "3.0.1"
+ }
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
+ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
+ "dev": true,
+ "requires": {
+ "estraverse": "4.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ }
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
+ "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+ "dev": true,
+ "requires": {
+ "estraverse": "4.2.0",
+ "object-assign": "4.1.1"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+ "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.39"
+ }
+ },
+ "eventemitter3": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
+ "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=",
+ "dev": true
+ },
+ "exit-hook": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+ "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
+ "dev": true
+ },
+ "expand-braces": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
+ "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=",
+ "dev": true,
+ "requires": {
+ "array-slice": "0.2.3",
+ "array-unique": "0.2.1",
+ "braces": "0.1.5"
+ },
+ "dependencies": {
+ "array-slice": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
+ "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+ "dev": true
+ },
+ "braces": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz",
+ "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=",
+ "dev": true,
+ "requires": {
+ "expand-range": "0.1.1"
+ }
+ },
+ "expand-range": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz",
+ "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=",
+ "dev": true,
+ "requires": {
+ "is-number": "0.1.1",
+ "repeat-string": "0.2.2"
+ }
+ },
+ "is-number": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz",
+ "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz",
+ "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=",
+ "dev": true
+ }
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "posix-character-classes": "0.1.1",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+ "dev": true,
+ "requires": {
+ "fill-range": "2.2.3"
+ },
+ "dependencies": {
+ "fill-range": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+ "dev": true,
+ "requires": {
+ "is-number": "2.1.0",
+ "isobject": "2.1.0",
+ "randomatic": "1.1.7",
+ "repeat-element": "1.1.2",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "1.0.1"
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "expand-brackets": "2.1.4",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "extract-zip": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
+ "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.0",
+ "debug": "2.6.9",
+ "mkdirp": "0.5.0",
+ "yauzl": "2.4.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+ "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "falafel": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz",
+ "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=",
+ "dev": true,
+ "requires": {
+ "acorn": "5.4.1",
+ "foreach": "2.0.5",
+ "isarray": "0.0.1",
+ "object-keys": "1.0.11"
+ }
+ },
+ "fancy-log": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz",
+ "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=",
+ "dev": true,
+ "requires": {
+ "ansi-gray": "0.1.1",
+ "color-support": "1.1.3",
+ "time-stamp": "1.1.0"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "fd-slicer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+ "dev": true,
+ "requires": {
+ "pend": "1.2.0"
+ }
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "1.0.5",
+ "object-assign": "4.1.1"
+ }
+ },
+ "file-entry-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+ "dev": true,
+ "requires": {
+ "flat-cache": "1.3.0",
+ "object-assign": "4.1.1"
+ }
+ },
+ "filename-regex": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1",
+ "to-regex-range": "2.1.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "statuses": "1.3.1",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+ "dev": true
+ }
+ }
+ },
+ "find-index": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz",
+ "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=",
+ "dev": true
+ },
+ "find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "requires": {
+ "path-exists": "2.1.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "findup-sync": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+ "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+ "dev": true,
+ "requires": {
+ "detect-file": "1.0.0",
+ "is-glob": "3.1.0",
+ "micromatch": "3.1.9",
+ "resolve-dir": "1.0.1"
+ }
+ },
+ "fined": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz",
+ "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "2.0.2",
+ "is-plain-object": "2.0.4",
+ "object.defaults": "1.1.0",
+ "object.pick": "1.3.0",
+ "parse-filepath": "1.0.2"
+ }
+ },
+ "first-chunk-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz",
+ "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=",
+ "dev": true
+ },
+ "flagged-respawn": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz",
+ "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=",
+ "dev": true
+ },
+ "flat-cache": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+ "dev": true,
+ "requires": {
+ "circular-json": "0.3.3",
+ "del": "2.2.2",
+ "graceful-fs": "4.1.11",
+ "write": "0.2.1"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ }
+ }
+ },
+ "fontkit": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-1.7.7.tgz",
+ "integrity": "sha1-668tjz/t8wKuPGS0vurdwkf827E=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "brfs": "1.4.4",
+ "brotli": "1.3.2",
+ "browserify-optional": "1.0.1",
+ "clone": "1.0.3",
+ "deep-equal": "1.0.1",
+ "dfa": "1.1.0",
+ "restructure": "0.5.4",
+ "tiny-inflate": "1.0.2",
+ "unicode-properties": "1.1.0",
+ "unicode-trie": "0.3.1"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2"
+ }
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.6",
+ "mime-types": "2.1.18"
+ }
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "0.2.2"
+ }
+ },
+ "fs-extra": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "jsonfile": "2.4.0",
+ "klaw": "1.3.1"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ }
+ }
+ },
+ "fs-readfile-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fs-readfile-promise/-/fs-readfile-promise-2.0.1.tgz",
+ "integrity": "sha1-gAI4I5gfn//+AWCei+Zo9prknnA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ }
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
+ "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "nan": "2.9.2",
+ "node-pre-gyp": "0.6.39"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
+ "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=",
+ "dev": true,
+ "optional": true
+ },
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "co": "4.6.0",
+ "json-stable-stringify": "1.0.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "aproba": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz",
+ "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=",
+ "dev": true,
+ "optional": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
+ "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "delegates": "1.0.0",
+ "readable-stream": "2.2.9"
+ }
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+ "dev": true,
+ "optional": true
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true,
+ "optional": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true,
+ "optional": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true,
+ "optional": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+ "dev": true,
+ "optional": true
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "block-stream": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
+ "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "0.4.2",
+ "concat-map": "0.0.1"
+ }
+ },
+ "buffer-shims": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+ "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true,
+ "optional": true
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true,
+ "optional": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+ "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
+ "dev": true,
+ "optional": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "dev": true,
+ "optional": true
+ },
+ "detect-libc": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.2.tgz",
+ "integrity": "sha1-ca1dIEvxempsqPRQxhRUBm70YeE=",
+ "dev": true,
+ "optional": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true,
+ "optional": true
+ },
+ "extsprintf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
+ "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true,
+ "optional": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.15"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fstream": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+ "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "inherits": "2.0.3",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.6.1"
+ }
+ },
+ "fstream-ignore": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
+ "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "fstream": "1.0.11",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4"
+ }
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aproba": "1.1.1",
+ "console-control-strings": "1.1.0",
+ "has-unicode": "2.0.1",
+ "object-assign": "4.1.1",
+ "signal-exit": "3.0.2",
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wide-align": "1.1.2"
+ }
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "har-schema": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
+ "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
+ "dev": true,
+ "optional": true
+ },
+ "har-validator": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
+ "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ajv": "4.11.8",
+ "har-schema": "1.0.5"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "dev": true,
+ "optional": true
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1",
+ "cryptiles": "2.0.5",
+ "hoek": "2.16.3",
+ "sntp": "1.0.9"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "0.2.0",
+ "jsprim": "1.4.0",
+ "sshpk": "1.13.0"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+ "dev": true,
+ "optional": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true,
+ "optional": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true,
+ "optional": true
+ },
+ "jodid25519": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz",
+ "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true,
+ "optional": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true,
+ "optional": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsonify": "0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true,
+ "optional": true
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true,
+ "optional": true
+ },
+ "jsprim": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
+ "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.0.2",
+ "json-schema": "0.2.3",
+ "verror": "1.3.6"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "mime-db": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
+ "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.15",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
+ "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.27.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true,
+ "optional": true
+ },
+ "node-pre-gyp": {
+ "version": "0.6.39",
+ "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz",
+ "integrity": "sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "detect-libc": "1.0.2",
+ "hawk": "3.1.3",
+ "mkdirp": "0.5.1",
+ "nopt": "4.0.1",
+ "npmlog": "4.1.0",
+ "rc": "1.2.1",
+ "request": "2.81.0",
+ "rimraf": "2.6.1",
+ "semver": "5.3.0",
+ "tar": "2.2.1",
+ "tar-pack": "3.4.0"
+ }
+ },
+ "nopt": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
+ "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "abbrev": "1.1.0",
+ "osenv": "0.1.4"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.0.tgz",
+ "integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "are-we-there-yet": "1.1.4",
+ "console-control-strings": "1.1.0",
+ "gauge": "2.7.4",
+ "set-blocking": "2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true,
+ "optional": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true,
+ "optional": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true,
+ "optional": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true,
+ "optional": true
+ },
+ "osenv": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
+ "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "os-homedir": "1.0.2",
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+ "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+ "dev": true,
+ "optional": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true,
+ "optional": true
+ },
+ "qs": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+ "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+ "dev": true,
+ "optional": true
+ },
+ "rc": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
+ "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "deep-extend": "0.4.2",
+ "ini": "1.3.4",
+ "minimist": "1.2.0",
+ "strip-json-comments": "2.0.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.2.9",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz",
+ "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=",
+ "dev": true,
+ "requires": {
+ "buffer-shims": "1.0.0",
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "string_decoder": "1.0.1",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "request": {
+ "version": "2.81.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
+ "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.1.4",
+ "har-validator": "4.2.1",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.15",
+ "oauth-sign": "0.8.2",
+ "performance-now": "0.2.0",
+ "qs": "6.4.0",
+ "safe-buffer": "5.0.1",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.2",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.0.1"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
+ "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
+ "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+ "dev": true,
+ "optional": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true,
+ "optional": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true,
+ "optional": true
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "sshpk": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz",
+ "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jodid25519": "1.0.2",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz",
+ "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.0.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+ "dev": true,
+ "optional": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true,
+ "optional": true
+ },
+ "tar": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+ "dev": true,
+ "requires": {
+ "block-stream": "0.0.9",
+ "fstream": "1.0.11",
+ "inherits": "2.0.3"
+ }
+ },
+ "tar-pack": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.0.tgz",
+ "integrity": "sha1-I74tf2cagzk3bL2wuP4/3r8xeYQ=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "debug": "2.6.8",
+ "fstream": "1.0.11",
+ "fstream-ignore": "1.0.5",
+ "once": "1.4.0",
+ "readable-stream": "2.2.9",
+ "rimraf": "2.6.1",
+ "tar": "2.2.1",
+ "uid-number": "0.0.6"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
+ "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true,
+ "optional": true
+ },
+ "uid-number": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz",
+ "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=",
+ "dev": true,
+ "optional": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz",
+ "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=",
+ "dev": true,
+ "optional": true
+ },
+ "verror": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
+ "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "extsprintf": "1.0.2"
+ }
+ },
+ "wide-align": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
+ "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "string-width": "1.0.2"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ }
+ }
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "gaze": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz",
+ "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=",
+ "dev": true,
+ "requires": {
+ "globule": "0.1.0"
+ }
+ },
+ "generate-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
+ "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
+ "dev": true
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+ "dev": true,
+ "requires": {
+ "is-property": "1.0.2"
+ }
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+ "dev": true
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "gl-matrix": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-2.4.0.tgz",
+ "integrity": "sha1-IImxMwGinuyCLZ2Z3/wfeO6aPFA=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "glob-base": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+ "dev": true,
+ "requires": {
+ "glob-parent": "2.0.0",
+ "is-glob": "2.0.1"
+ },
+ "dependencies": {
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ }
+ }
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "dev": true,
+ "requires": {
+ "is-glob": "2.0.1"
+ },
+ "dependencies": {
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ }
+ }
+ },
+ "glob-stream": {
+ "version": "3.1.18",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz",
+ "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=",
+ "dev": true,
+ "requires": {
+ "glob": "4.5.3",
+ "glob2base": "0.0.12",
+ "minimatch": "2.0.10",
+ "ordered-read-streams": "0.1.0",
+ "through2": "0.6.5",
+ "unique-stream": "1.0.0"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz",
+ "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=",
+ "dev": true,
+ "requires": {
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "2.0.10",
+ "once": "1.4.0"
+ }
+ },
+ "minimatch": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
+ "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.11"
+ }
+ },
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "through2": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
+ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.0.34",
+ "xtend": "4.0.1"
+ }
+ }
+ }
+ },
+ "glob-watcher": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz",
+ "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=",
+ "dev": true,
+ "requires": {
+ "gaze": "0.5.2"
+ }
+ },
+ "glob2base": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz",
+ "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=",
+ "dev": true,
+ "requires": {
+ "find-index": "0.1.1"
+ }
+ },
+ "global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "1.0.2",
+ "is-windows": "1.0.2",
+ "resolve-dir": "1.0.1"
+ }
+ },
+ "global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "2.0.2",
+ "homedir-polyfill": "1.0.1",
+ "ini": "1.3.5",
+ "is-windows": "1.0.2",
+ "which": "1.3.0"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "globby": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "arrify": "1.0.1",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "globule": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz",
+ "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=",
+ "dev": true,
+ "requires": {
+ "glob": "3.1.21",
+ "lodash": "1.0.2",
+ "minimatch": "0.2.14"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "3.1.21",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
+ "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "1.2.3",
+ "inherits": "1.0.2",
+ "minimatch": "0.2.14"
+ }
+ },
+ "graceful-fs": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
+ "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=",
+ "dev": true
+ },
+ "inherits": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
+ "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+ "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "2.7.3",
+ "sigmund": "1.0.1"
+ }
+ }
+ }
+ },
+ "glogg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz",
+ "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==",
+ "dev": true,
+ "requires": {
+ "sparkles": "1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
+ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
+ "dev": true,
+ "requires": {
+ "natives": "1.1.1"
+ }
+ },
+ "gulp": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz",
+ "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=",
+ "dev": true,
+ "requires": {
+ "archy": "1.0.0",
+ "chalk": "1.1.3",
+ "deprecated": "0.0.1",
+ "gulp-util": "3.0.8",
+ "interpret": "1.1.0",
+ "liftoff": "2.5.0",
+ "minimist": "1.2.0",
+ "orchestrator": "0.3.8",
+ "pretty-hrtime": "1.0.3",
+ "semver": "4.3.6",
+ "tildify": "1.2.0",
+ "v8flags": "2.1.1",
+ "vinyl-fs": "0.3.14"
+ }
+ },
+ "gulp-chmod": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-chmod/-/gulp-chmod-2.0.0.tgz",
+ "integrity": "sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw=",
+ "dev": true,
+ "requires": {
+ "deep-assign": "1.0.0",
+ "stat-mode": "0.2.2",
+ "through2": "2.0.3"
+ }
+ },
+ "gulp-cli": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-1.4.0.tgz",
+ "integrity": "sha1-b1u+LNC9tISdEs+eEkalhh+LT4g=",
+ "dev": true,
+ "requires": {
+ "archy": "1.0.0",
+ "chalk": "1.1.3",
+ "copy-props": "1.6.0",
+ "fancy-log": "1.3.2",
+ "gulplog": "1.0.0",
+ "interpret": "1.1.0",
+ "liftoff": "2.5.0",
+ "lodash.isfunction": "3.0.9",
+ "lodash.isplainobject": "4.0.6",
+ "lodash.sortby": "4.7.0",
+ "matchdep": "1.0.1",
+ "mute-stdout": "1.0.0",
+ "pretty-hrtime": "1.0.3",
+ "semver-greatest-satisfied-range": "1.1.0",
+ "tildify": "1.2.0",
+ "v8flags": "2.1.1",
+ "wreck": "6.3.0",
+ "yargs": "3.32.0"
+ }
+ },
+ "gulp-concat": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz",
+ "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=",
+ "dev": true,
+ "requires": {
+ "concat-with-sourcemaps": "1.0.5",
+ "through2": "2.0.3",
+ "vinyl": "2.1.0"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
+ "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
+ "dev": true
+ },
+ "clone-stats": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+ "dev": true
+ },
+ "replace-ext": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz",
+ "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=",
+ "dev": true,
+ "requires": {
+ "clone": "2.1.1",
+ "clone-buffer": "1.0.0",
+ "clone-stats": "1.0.0",
+ "cloneable-readable": "1.0.0",
+ "remove-trailing-separator": "1.1.0",
+ "replace-ext": "1.0.0"
+ }
+ }
+ }
+ },
+ "gulp-header": {
+ "version": "1.8.9",
+ "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.9.tgz",
+ "integrity": "sha1-yfEP7gYy2B6Tl4nG7PRaFRvzCYs=",
+ "dev": true,
+ "requires": {
+ "concat-with-sourcemaps": "1.0.5",
+ "gulp-util": "3.0.8",
+ "object-assign": "4.1.1",
+ "through2": "2.0.3"
+ }
+ },
+ "gulp-rename": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz",
+ "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=",
+ "dev": true
+ },
+ "gulp-size": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/gulp-size/-/gulp-size-2.1.0.tgz",
+ "integrity": "sha1-HCtk8X+QcdWr2Z0VS3s0gfj7oSg=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "gulp-util": "3.0.8",
+ "gzip-size": "3.0.0",
+ "object-assign": "4.1.1",
+ "pretty-bytes": "3.0.1",
+ "stream-counter": "1.0.0",
+ "through2": "2.0.3"
+ }
+ },
+ "gulp-standard": {
+ "version": "10.1.2",
+ "resolved": "https://registry.npmjs.org/gulp-standard/-/gulp-standard-10.1.2.tgz",
+ "integrity": "sha512-w+VBktDzONh807qzV5FvngPgmzuGRWu7oMlIpIvOOmSPlyy/ixM138DGOuMWy1M9bRVMDKEfQSj0aGB2ZjzQSA==",
+ "dev": true,
+ "requires": {
+ "app-root-path": "2.0.1",
+ "colors": "1.1.2",
+ "log-symbols": "1.0.2",
+ "path": "0.12.7",
+ "plugin-error": "1.0.1",
+ "standard": "10.0.3",
+ "through2": "2.0.3"
+ },
+ "dependencies": {
+ "eslint": {
+ "version": "3.19.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz",
+ "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "chalk": "1.1.3",
+ "concat-stream": "1.6.0",
+ "debug": "2.6.9",
+ "doctrine": "2.1.0",
+ "escope": "3.6.0",
+ "espree": "3.5.3",
+ "esquery": "1.0.0",
+ "estraverse": "4.2.0",
+ "esutils": "2.0.2",
+ "file-entry-cache": "2.0.0",
+ "glob": "7.1.2",
+ "globals": "9.18.0",
+ "ignore": "3.3.7",
+ "imurmurhash": "0.1.4",
+ "inquirer": "0.12.0",
+ "is-my-json-valid": "2.17.2",
+ "is-resolvable": "1.1.0",
+ "js-yaml": "3.6.1",
+ "json-stable-stringify": "1.0.1",
+ "levn": "0.3.0",
+ "lodash": "4.17.5",
+ "mkdirp": "0.5.1",
+ "natural-compare": "1.4.0",
+ "optionator": "0.8.2",
+ "path-is-inside": "1.0.2",
+ "pluralize": "1.2.1",
+ "progress": "1.1.8",
+ "require-uncached": "1.0.3",
+ "shelljs": "0.7.8",
+ "strip-bom": "3.0.0",
+ "strip-json-comments": "2.0.1",
+ "table": "3.8.3",
+ "text-table": "0.2.0",
+ "user-home": "2.0.0"
+ }
+ },
+ "eslint-config-standard": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz",
+ "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=",
+ "dev": true
+ },
+ "eslint-config-standard-jsx": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz",
+ "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==",
+ "dev": true
+ },
+ "eslint-plugin-promise": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz",
+ "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=",
+ "dev": true
+ },
+ "eslint-plugin-react": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz",
+ "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=",
+ "dev": true,
+ "requires": {
+ "array.prototype.find": "2.0.4",
+ "doctrine": "1.5.0",
+ "has": "1.0.1",
+ "jsx-ast-utils": "1.4.1",
+ "object.assign": "4.1.0"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "2.0.2",
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-standard": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz",
+ "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=",
+ "dev": true
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ },
+ "plugin-error": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
+ "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "1.1.0",
+ "arr-diff": "4.0.0",
+ "arr-union": "3.1.0",
+ "extend-shallow": "3.0.2"
+ }
+ },
+ "standard": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz",
+ "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==",
+ "dev": true,
+ "requires": {
+ "eslint": "3.19.0",
+ "eslint-config-standard": "10.2.1",
+ "eslint-config-standard-jsx": "4.0.2",
+ "eslint-plugin-import": "2.2.0",
+ "eslint-plugin-node": "4.2.3",
+ "eslint-plugin-promise": "3.5.0",
+ "eslint-plugin-react": "6.10.3",
+ "eslint-plugin-standard": "3.0.1",
+ "standard-engine": "7.0.0"
+ }
+ },
+ "standard-engine": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz",
+ "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=",
+ "dev": true,
+ "requires": {
+ "deglob": "2.1.0",
+ "get-stdin": "5.0.1",
+ "minimist": "1.2.0",
+ "pkg-conf": "2.1.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "user-home": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+ "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "1.0.2"
+ }
+ }
+ }
+ },
+ "gulp-trimlines": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gulp-trimlines/-/gulp-trimlines-1.0.1.tgz",
+ "integrity": "sha1-exeRa4UMoPBa9BkN0k6aweJunyY=",
+ "dev": true,
+ "requires": {
+ "through2": "0.6.5"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "through2": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
+ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.0.34",
+ "xtend": "4.0.1"
+ }
+ }
+ }
+ },
+ "gulp-uglify": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-2.1.2.tgz",
+ "integrity": "sha1-bbhbHQ7mPRgFhZK2WGSdZcLsRUE=",
+ "dev": true,
+ "requires": {
+ "gulplog": "1.0.0",
+ "has-gulplog": "0.1.0",
+ "lodash": "4.17.5",
+ "make-error-cause": "1.2.2",
+ "through2": "2.0.3",
+ "uglify-js": "2.8.29",
+ "uglify-save-license": "0.4.1",
+ "vinyl-sourcemaps-apply": "0.2.1"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ }
+ }
+ },
+ "gulp-util": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz",
+ "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=",
+ "dev": true,
+ "requires": {
+ "array-differ": "1.0.0",
+ "array-uniq": "1.0.3",
+ "beeper": "1.1.1",
+ "chalk": "1.1.3",
+ "dateformat": "2.2.0",
+ "fancy-log": "1.3.2",
+ "gulplog": "1.0.0",
+ "has-gulplog": "0.1.0",
+ "lodash._reescape": "3.0.0",
+ "lodash._reevaluate": "3.0.0",
+ "lodash._reinterpolate": "3.0.0",
+ "lodash.template": "3.6.2",
+ "minimist": "1.2.0",
+ "multipipe": "0.1.2",
+ "object-assign": "3.0.0",
+ "replace-ext": "0.0.1",
+ "through2": "2.0.3",
+ "vinyl": "0.5.3"
+ },
+ "dependencies": {
+ "object-assign": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
+ "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=",
+ "dev": true
+ }
+ }
+ },
+ "gulp-wrap": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/gulp-wrap/-/gulp-wrap-0.13.0.tgz",
+ "integrity": "sha1-kPsLSieiZkM4Mv98YSLbXB7olMY=",
+ "dev": true,
+ "requires": {
+ "consolidate": "0.14.5",
+ "es6-promise": "3.3.1",
+ "fs-readfile-promise": "2.0.1",
+ "gulp-util": "3.0.8",
+ "js-yaml": "3.6.1",
+ "lodash": "4.17.5",
+ "node.extend": "1.1.6",
+ "through2": "2.0.3",
+ "tryit": "1.0.3",
+ "vinyl-bufferstream": "1.0.1"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ }
+ }
+ },
+ "gulplog": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
+ "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
+ "dev": true,
+ "requires": {
+ "glogg": "1.0.1"
+ }
+ },
+ "gzip-size": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz",
+ "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=",
+ "dev": true,
+ "requires": {
+ "duplexer": "0.1.1"
+ }
+ },
+ "handlebars": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz",
+ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=",
+ "dev": true,
+ "requires": {
+ "async": "1.5.2",
+ "optimist": "0.6.1",
+ "source-map": "0.4.4",
+ "uglify-js": "2.8.29"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "commander": "2.14.1",
+ "is-my-json-valid": "2.17.2",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "has": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
+ "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
+ "dev": true,
+ "requires": {
+ "function-bind": "1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "has-binary": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz",
+ "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=",
+ "dev": true,
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ },
+ "has-cors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+ "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "has-gulplog": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz",
+ "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=",
+ "dev": true,
+ "requires": {
+ "sparkles": "1.0.0"
+ }
+ },
+ "has-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+ "dev": true
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "1.0.0",
+ "isobject": "3.0.1"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "hasha": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
+ "dev": true,
+ "requires": {
+ "is-stream": "1.1.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1",
+ "cryptiles": "2.0.5",
+ "hoek": "2.16.3",
+ "sntp": "1.0.9"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ },
+ "home-or-tmp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "1.0.2",
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "homedir-polyfill": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "1.0.0"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+ "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "dev": true,
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": "1.4.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
+ "dev": true
+ }
+ }
+ },
+ "http-proxy": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz",
+ "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=",
+ "dev": true,
+ "requires": {
+ "eventemitter3": "1.2.0",
+ "requires-port": "1.0.0"
+ }
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "0.2.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
+ "dev": true
+ },
+ "ignore": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz",
+ "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==",
+ "dev": true
+ },
+ "image-size": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+ "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+ "dev": true,
+ "requires": {
+ "repeating": "2.0.1"
+ }
+ },
+ "indexof": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
+ "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "1.4.0",
+ "ansi-regex": "2.1.1",
+ "chalk": "1.1.3",
+ "cli-cursor": "1.0.2",
+ "cli-width": "2.2.0",
+ "figures": "1.7.0",
+ "lodash": "4.17.5",
+ "readline2": "1.0.1",
+ "run-async": "0.1.0",
+ "rx-lite": "3.1.2",
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "through": "2.3.8"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ }
+ }
+ },
+ "interpret": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+ "dev": true
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true
+ },
+ "is": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz",
+ "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=",
+ "dev": true
+ },
+ "is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "dev": true,
+ "requires": {
+ "is-relative": "1.0.0",
+ "is-windows": "1.0.2"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "1.11.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "1.1.1"
+ }
+ },
+ "is-callable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
+ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+ "dev": true
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-dotfile": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+ "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
+ "dev": true
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+ "dev": true,
+ "requires": {
+ "is-primitive": "2.0.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ },
+ "is-my-ip-valid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
+ "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
+ "dev": true
+ },
+ "is-my-json-valid": {
+ "version": "2.17.2",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz",
+ "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==",
+ "dev": true,
+ "requires": {
+ "generate-function": "2.0.0",
+ "generate-object-property": "1.2.0",
+ "is-my-ip-valid": "1.0.0",
+ "jsonpointer": "4.0.1",
+ "xtend": "4.0.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true
+ },
+ "is-odd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+ "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true
+ }
+ }
+ },
+ "is-path-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+ "dev": true,
+ "requires": {
+ "is-path-inside": "1.0.1"
+ }
+ },
+ "is-path-inside": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "1.0.2"
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+ "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
+ "dev": true
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
+ "dev": true
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "dev": true,
+ "requires": {
+ "has": "1.0.1"
+ }
+ },
+ "is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "dev": true,
+ "requires": {
+ "is-unc-path": "1.0.0"
+ }
+ },
+ "is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-symbol": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
+ "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "dev": true,
+ "requires": {
+ "unc-path-regex": "0.1.2"
+ }
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "isbinaryfile": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz",
+ "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "istanbul": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
+ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.0.9",
+ "async": "1.5.2",
+ "escodegen": "1.8.1",
+ "esprima": "2.7.3",
+ "glob": "5.0.15",
+ "handlebars": "4.0.11",
+ "js-yaml": "3.6.1",
+ "mkdirp": "0.5.1",
+ "nopt": "3.0.6",
+ "once": "1.4.0",
+ "resolve": "1.1.7",
+ "supports-color": "3.2.3",
+ "which": "1.3.0",
+ "wordwrap": "1.0.0"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "dev": true,
+ "requires": {
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ }
+ }
+ },
+ "jasmine-core": {
+ "version": "2.99.1",
+ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
+ "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz",
+ "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=",
+ "dev": true,
+ "requires": {
+ "argparse": "1.0.10",
+ "esprima": "2.7.3"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true,
+ "optional": true
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz",
+ "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "requires": {
+ "jsonify": "0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "json3": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
+ "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "jsx-ast-utils": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz",
+ "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=",
+ "dev": true
+ },
+ "karma": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz",
+ "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.5.1",
+ "body-parser": "1.18.2",
+ "chokidar": "1.7.0",
+ "colors": "1.1.2",
+ "combine-lists": "1.0.1",
+ "connect": "3.6.6",
+ "core-js": "2.5.3",
+ "di": "0.0.1",
+ "dom-serialize": "2.2.1",
+ "expand-braces": "0.1.2",
+ "glob": "7.1.2",
+ "graceful-fs": "4.1.11",
+ "http-proxy": "1.16.2",
+ "isbinaryfile": "3.0.2",
+ "lodash": "3.10.1",
+ "log4js": "0.6.38",
+ "mime": "1.6.0",
+ "minimatch": "3.0.4",
+ "optimist": "0.6.1",
+ "qjobs": "1.2.0",
+ "range-parser": "1.2.0",
+ "rimraf": "2.6.2",
+ "safe-buffer": "5.1.1",
+ "socket.io": "1.7.3",
+ "source-map": "0.5.7",
+ "tmp": "0.0.31",
+ "useragent": "2.3.0"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ }
+ }
+ },
+ "karma-coverage": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.1.tgz",
+ "integrity": "sha1-Wv+LOc9plNwi3kyENix2ABtjfPY=",
+ "dev": true,
+ "requires": {
+ "dateformat": "1.0.12",
+ "istanbul": "0.4.5",
+ "lodash": "3.10.1",
+ "minimatch": "3.0.4",
+ "source-map": "0.5.7"
+ },
+ "dependencies": {
+ "dateformat": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "4.0.1",
+ "meow": "3.7.0"
+ }
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ }
+ }
+ },
+ "karma-firefox-launcher": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz",
+ "integrity": "sha512-LbZ5/XlIXLeQ3cqnCbYLn+rOVhuMIK9aZwlP6eOLGzWdo1UVp7t6CN3DP4SafiRLjexKwHeKHDm0c38Mtd3VxA==",
+ "dev": true
+ },
+ "karma-jasmine": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.1.tgz",
+ "integrity": "sha1-b+hA51oRYAydkehLM8RY4cRqNSk=",
+ "dev": true
+ },
+ "karma-phantomjs-launcher": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz",
+ "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=",
+ "dev": true,
+ "requires": {
+ "lodash": "4.17.5",
+ "phantomjs-prebuilt": "2.1.16"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ }
+ }
+ },
+ "kew": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "lazy-cache": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
+ "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
+ "dev": true,
+ "requires": {
+ "set-getter": "0.1.0"
+ }
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
+ "requires": {
+ "invert-kv": "1.0.0"
+ }
+ },
+ "lcov-parse": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz",
+ "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2"
+ }
+ },
+ "liftoff": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz",
+ "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=",
+ "dev": true,
+ "requires": {
+ "extend": "3.0.1",
+ "findup-sync": "2.0.0",
+ "fined": "1.1.0",
+ "flagged-respawn": "1.0.0",
+ "is-plain-object": "2.0.4",
+ "object.map": "1.0.1",
+ "rechoir": "0.6.2",
+ "resolve": "1.5.0"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "strip-bom": "2.0.0"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "dev": true,
+ "requires": {
+ "is-utf8": "0.2.1"
+ }
+ }
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "2.0.0",
+ "path-exists": "3.0.0"
+ },
+ "dependencies": {
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ }
+ }
+ },
+ "lodash": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz",
+ "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=",
+ "dev": true
+ },
+ "lodash._basecopy": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
+ "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
+ "dev": true
+ },
+ "lodash._basetostring": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz",
+ "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=",
+ "dev": true
+ },
+ "lodash._basevalues": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz",
+ "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=",
+ "dev": true
+ },
+ "lodash._getnative": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+ "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
+ "dev": true
+ },
+ "lodash._isiterateecall": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
+ "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=",
+ "dev": true
+ },
+ "lodash._reescape": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz",
+ "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=",
+ "dev": true
+ },
+ "lodash._reevaluate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz",
+ "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=",
+ "dev": true
+ },
+ "lodash._reinterpolate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
+ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
+ "dev": true
+ },
+ "lodash._root": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
+ "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=",
+ "dev": true
+ },
+ "lodash.cond": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
+ "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=",
+ "dev": true
+ },
+ "lodash.escape": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz",
+ "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=",
+ "dev": true,
+ "requires": {
+ "lodash._root": "3.0.1"
+ }
+ },
+ "lodash.isarguments": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+ "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
+ "dev": true
+ },
+ "lodash.isarray": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+ "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
+ "dev": true
+ },
+ "lodash.isfunction": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
+ "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==",
+ "dev": true
+ },
+ "lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
+ "dev": true
+ },
+ "lodash.keys": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+ "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+ "dev": true,
+ "requires": {
+ "lodash._getnative": "3.9.1",
+ "lodash.isarguments": "3.1.0",
+ "lodash.isarray": "3.0.4"
+ }
+ },
+ "lodash.restparam": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
+ "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=",
+ "dev": true
+ },
+ "lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+ "dev": true
+ },
+ "lodash.template": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz",
+ "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=",
+ "dev": true,
+ "requires": {
+ "lodash._basecopy": "3.0.1",
+ "lodash._basetostring": "3.0.1",
+ "lodash._basevalues": "3.0.0",
+ "lodash._isiterateecall": "3.0.9",
+ "lodash._reinterpolate": "3.0.0",
+ "lodash.escape": "3.2.0",
+ "lodash.keys": "3.1.2",
+ "lodash.restparam": "3.6.1",
+ "lodash.templatesettings": "3.1.1"
+ }
+ },
+ "lodash.templatesettings": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz",
+ "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=",
+ "dev": true,
+ "requires": {
+ "lodash._reinterpolate": "3.0.0",
+ "lodash.escape": "3.2.0"
+ }
+ },
+ "log-driver": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz",
+ "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+ "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3"
+ }
+ },
+ "log4js": {
+ "version": "0.6.38",
+ "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz",
+ "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.0.34",
+ "semver": "4.3.6"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ }
+ }
+ },
+ "longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+ "dev": true
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "dev": true,
+ "requires": {
+ "currently-unhandled": "0.4.1",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "lru-cache": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
+ "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
+ "dev": true
+ },
+ "make-error": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz",
+ "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==",
+ "dev": true
+ },
+ "make-error-cause": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz",
+ "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=",
+ "dev": true,
+ "requires": {
+ "make-error": "1.3.4"
+ }
+ },
+ "make-iterator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.0.tgz",
+ "integrity": "sha1-V7713IXSOSO6I3ZzJNjo+PPZaUs=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "1.0.1"
+ }
+ },
+ "matchdep": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-1.0.1.tgz",
+ "integrity": "sha1-pXozgESR+64girqPaDgEN6vC3KU=",
+ "dev": true,
+ "requires": {
+ "findup-sync": "0.3.0",
+ "micromatch": "2.3.11",
+ "resolve": "1.1.7",
+ "stack-trace": "0.0.9"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.1.0"
+ }
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+ "dev": true
+ },
+ "braces": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+ "dev": true,
+ "requires": {
+ "expand-range": "1.8.2",
+ "preserve": "0.2.0",
+ "repeat-element": "1.1.2"
+ }
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+ "dev": true,
+ "requires": {
+ "is-posix-bracket": "0.1.1"
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "findup-sync": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
+ "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
+ "dev": true,
+ "requires": {
+ "glob": "5.0.15"
+ }
+ },
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "dev": true,
+ "requires": {
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+ "dev": true,
+ "requires": {
+ "arr-diff": "2.0.0",
+ "array-unique": "0.2.1",
+ "braces": "1.8.5",
+ "expand-brackets": "0.1.5",
+ "extglob": "0.3.2",
+ "filename-regex": "2.0.1",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1",
+ "kind-of": "3.2.2",
+ "normalize-path": "2.1.1",
+ "object.omit": "2.0.1",
+ "parse-glob": "3.0.4",
+ "regex-cache": "0.4.4"
+ }
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ }
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "dev": true
+ },
+ "meow": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "2.1.0",
+ "decamelize": "1.2.0",
+ "loud-rejection": "1.6.0",
+ "map-obj": "1.0.1",
+ "minimist": "1.2.0",
+ "normalize-package-data": "2.4.0",
+ "object-assign": "4.1.1",
+ "read-pkg-up": "1.0.1",
+ "redent": "1.0.0",
+ "trim-newlines": "1.0.0"
+ }
+ },
+ "micromatch": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.9.tgz",
+ "integrity": "sha512-SlIz6sv5UPaAVVFRKodKjCg48EbNoIhgetzfK/Cy0v5U52Z6zB136M8tp0UC9jM53LYbmIRihJszvvqpKkfm9g==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "braces": "2.3.1",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "extglob": "2.0.4",
+ "fragment-cache": "0.2.1",
+ "kind-of": "6.0.2",
+ "nanomatch": "1.2.9",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.2"
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.33.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.11"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "mixin-deep": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ }
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "multipipe": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
+ "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=",
+ "dev": true,
+ "requires": {
+ "duplexer2": "0.0.2"
+ }
+ },
+ "mute-stdout": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.0.tgz",
+ "integrity": "sha1-WzLqB+tDyd7WEwQ0z5JvRrKn/U0=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
+ "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=",
+ "dev": true
+ },
+ "nan": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.9.2.tgz",
+ "integrity": "sha512-ltW65co7f3PQWBDbqVvaU1WtFJUsNW7sWWm4HINhbMQIyVyzIeyZ8toX5TC5eeooE6piZoaEh4cZkueSKG3KYw==",
+ "dev": true,
+ "optional": true
+ },
+ "nanomatch": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+ "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "fragment-cache": "0.2.1",
+ "is-odd": "2.0.0",
+ "is-windows": "1.0.2",
+ "kind-of": "6.0.2",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.2"
+ }
+ },
+ "natives": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz",
+ "integrity": "sha512-8eRaxn8u/4wN8tGkhlc2cgwwvOLMLUMUn4IYTexMgWd+LyUDfeXVkk2ygQR0hvIHbJQXgHujia3ieUUDwNGkEA==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+ "dev": true
+ },
+ "node.extend": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz",
+ "integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=",
+ "dev": true,
+ "requires": {
+ "is": "3.2.1"
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.0.9"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "2.5.0",
+ "is-builtin-module": "1.0.0",
+ "semver": "4.3.6",
+ "validate-npm-package-license": "3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "1.1.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object-component": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
+ "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
+ "dev": true
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "0.1.1",
+ "define-property": "0.2.5",
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "object-inspect": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz",
+ "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
+ "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
+ "dev": true
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dev": true,
+ "requires": {
+ "define-properties": "1.1.2",
+ "function-bind": "1.1.1",
+ "has-symbols": "1.0.0",
+ "object-keys": "1.0.11"
+ }
+ },
+ "object.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
+ "dev": true,
+ "requires": {
+ "array-each": "1.0.1",
+ "array-slice": "1.1.0",
+ "for-own": "1.0.0",
+ "isobject": "3.0.1"
+ }
+ },
+ "object.map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
+ "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
+ "dev": true,
+ "requires": {
+ "for-own": "1.0.0",
+ "make-iterator": "1.0.0"
+ }
+ },
+ "object.omit": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+ "dev": true,
+ "requires": {
+ "for-own": "0.1.5",
+ "is-extendable": "0.1.1"
+ },
+ "dependencies": {
+ "for-own": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2"
+ }
+ }
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "onetime": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+ "dev": true
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.10",
+ "wordwrap": "0.0.2"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+ "dev": true
+ }
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "0.1.3",
+ "fast-levenshtein": "2.0.6",
+ "levn": "0.3.0",
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2",
+ "wordwrap": "1.0.0"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ }
+ }
+ },
+ "options": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
+ "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=",
+ "dev": true
+ },
+ "orchestrator": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz",
+ "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "0.1.5",
+ "sequencify": "0.0.7",
+ "stream-consume": "0.1.1"
+ }
+ },
+ "ordered-read-streams": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz",
+ "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=",
+ "dev": true
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
+ "requires": {
+ "lcid": "1.0.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
+ "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
+ "dev": true,
+ "requires": {
+ "p-try": "1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "1.2.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
+ "dev": true
+ },
+ "parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+ "dev": true,
+ "requires": {
+ "is-absolute": "1.0.0",
+ "map-cache": "0.2.2",
+ "path-root": "0.1.1"
+ }
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+ "dev": true,
+ "requires": {
+ "glob-base": "0.3.0",
+ "is-dotfile": "1.0.3",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1"
+ },
+ "dependencies": {
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ }
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "1.3.1"
+ }
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "dev": true
+ },
+ "parsejson": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz",
+ "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=",
+ "dev": true,
+ "requires": {
+ "better-assert": "1.0.2"
+ }
+ },
+ "parseqs": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
+ "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
+ "dev": true,
+ "requires": {
+ "better-assert": "1.0.2"
+ }
+ },
+ "parseuri": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
+ "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
+ "dev": true,
+ "requires": {
+ "better-assert": "1.0.2"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path": {
+ "version": "0.12.7",
+ "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
+ "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=",
+ "dev": true,
+ "requires": {
+ "process": "0.11.10",
+ "util": "0.10.3"
+ }
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+ "dev": true
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+ "dev": true,
+ "requires": {
+ "path-root-regex": "0.1.2"
+ }
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ }
+ }
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
+ "phantomjs-prebuilt": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
+ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "4.2.4",
+ "extract-zip": "1.6.6",
+ "fs-extra": "1.0.0",
+ "hasha": "2.2.0",
+ "kew": "0.7.0",
+ "progress": "1.1.8",
+ "request": "2.83.0",
+ "request-progress": "2.0.1",
+ "which": "1.3.0"
+ },
+ "dependencies": {
+ "es6-promise": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
+ "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
+ "dev": true
+ }
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "pkg-conf": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
+ "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=",
+ "dev": true,
+ "requires": {
+ "find-up": "2.1.0",
+ "load-json-file": "4.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "2.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "4.0.0",
+ "pify": "3.0.0",
+ "strip-bom": "3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "1.3.1",
+ "json-parse-better-errors": "1.0.1"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ }
+ }
+ },
+ "pkg-config": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz",
+ "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=",
+ "dev": true,
+ "requires": {
+ "debug-log": "1.0.1",
+ "find-root": "1.1.0",
+ "xtend": "4.0.1"
+ }
+ },
+ "pkg-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
+ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2"
+ }
+ },
+ "pkg-up": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz",
+ "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=",
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2"
+ }
+ },
+ "pluralize": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+ "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
+ "dev": true
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
+ "dev": true
+ },
+ "pretty-bytes": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz",
+ "integrity": "sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
+ "dev": true
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+ "dev": true
+ },
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "qjobs": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
+ "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+ "dev": true
+ },
+ "quote-stream": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz",
+ "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=",
+ "dev": true,
+ "requires": {
+ "buffer-equal": "0.0.1",
+ "minimist": "1.2.0",
+ "through2": "2.0.3"
+ }
+ },
+ "randomatic": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+ "dev": true,
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "unpipe": "1.0.0"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "1.1.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "1.1.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2",
+ "read-pkg": "1.1.0"
+ }
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "readdirp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "minimatch": "3.0.4",
+ "readable-stream": "2.3.4",
+ "set-immediate-shim": "1.0.1"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
+ "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "readline2": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
+ "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "mute-stream": "0.0.5"
+ }
+ },
+ "rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "dev": true,
+ "requires": {
+ "resolve": "1.5.0"
+ }
+ },
+ "redent": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+ "dev": true,
+ "requires": {
+ "indent-string": "2.1.0",
+ "strip-indent": "1.0.1"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ },
+ "regex-cache": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+ "dev": true,
+ "requires": {
+ "is-equal-shallow": "0.1.3"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "3.0.2",
+ "safe-regex": "1.1.0"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "dev": true
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+ "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+ "dev": true,
+ "requires": {
+ "is-finite": "1.0.2"
+ }
+ },
+ "replace-ext": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
+ "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.83.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+ "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.7.0",
+ "aws4": "1.6.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.6",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.3.2",
+ "har-validator": "5.0.3",
+ "hawk": "6.0.2",
+ "http-signature": "1.2.0",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.18",
+ "oauth-sign": "0.8.2",
+ "performance-now": "2.1.0",
+ "qs": "6.5.1",
+ "safe-buffer": "5.1.1",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.2.1"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true
+ },
+ "boom": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.1"
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
+ "cryptiles": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+ "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+ "dev": true,
+ "requires": {
+ "boom": "5.2.0"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.1"
+ }
+ }
+ }
+ },
+ "form-data": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+ "dev": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.6",
+ "mime-types": "2.1.18"
+ }
+ },
+ "har-validator": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "dev": true,
+ "requires": {
+ "ajv": "5.5.2",
+ "har-schema": "2.0.0"
+ }
+ },
+ "hawk": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "dev": true,
+ "requires": {
+ "boom": "4.3.1",
+ "cryptiles": "3.1.2",
+ "hoek": "4.2.1",
+ "sntp": "2.1.0"
+ }
+ },
+ "hoek": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
+ "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+ "dev": true
+ },
+ "sntp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+ "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "request-progress": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
+ "dev": true,
+ "requires": {
+ "throttleit": "1.0.0"
+ }
+ },
+ "require-uncached": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+ "dev": true,
+ "requires": {
+ "caller-path": "0.1.0",
+ "resolve-from": "1.0.1"
+ }
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
+ "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
+ "dev": true,
+ "requires": {
+ "path-parse": "1.0.5"
+ }
+ },
+ "resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "2.0.2",
+ "global-modules": "1.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+ "dev": true
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+ "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+ "dev": true,
+ "requires": {
+ "exit-hook": "1.1.1",
+ "onetime": "1.1.0"
+ }
+ },
+ "restructure": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/restructure/-/restructure-0.5.4.tgz",
+ "integrity": "sha1-9U591WNZD7NP1r9Vh2EJrsyyjeg=",
+ "dev": true,
+ "requires": {
+ "browserify-optional": "1.0.1"
+ }
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+ "dev": true,
+ "requires": {
+ "align-text": "0.1.4"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "run-async": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
+ "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0"
+ }
+ },
+ "run-parallel": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.7.tgz",
+ "integrity": "sha512-nB641a6enJOh0fdsFHR9SiVCiOlAyjMplImDdjV3kWCzJZw9rwzvGwmpGuPmfX//Yxblh0pkzPcFcxA81iwmxA==",
+ "dev": true
+ },
+ "rx-lite": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+ "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+ "dev": true
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "0.1.15"
+ }
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true
+ },
+ "semver": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
+ "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=",
+ "dev": true
+ },
+ "semver-greatest-satisfied-range": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
+ "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=",
+ "dev": true,
+ "requires": {
+ "sver-compat": "1.5.0"
+ }
+ },
+ "sequencify": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz",
+ "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=",
+ "dev": true
+ },
+ "set-getter": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz",
+ "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=",
+ "dev": true,
+ "requires": {
+ "to-object-path": "0.3.0"
+ }
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+ "dev": true
+ },
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "split-string": "3.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
+ "dev": true
+ },
+ "shallow-copy": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz",
+ "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=",
+ "dev": true
+ },
+ "shelljs": {
+ "version": "0.7.8",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz",
+ "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2",
+ "interpret": "1.1.0",
+ "rechoir": "0.6.2"
+ }
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
+ "dev": true
+ },
+ "snapdragon": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz",
+ "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=",
+ "dev": true,
+ "requires": {
+ "base": "0.11.2",
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "map-cache": "0.2.2",
+ "source-map": "0.5.7",
+ "source-map-resolve": "0.5.1",
+ "use": "2.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "snapdragon-util": "3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "snazzy": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/snazzy/-/snazzy-6.0.0.tgz",
+ "integrity": "sha1-ahfUeYy7yLxuETFTaUkHqLrJSU0=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "inherits": "2.0.3",
+ "minimist": "1.2.0",
+ "readable-stream": "2.3.4",
+ "standard": "9.0.2",
+ "standard-json": "1.0.2",
+ "text-table": "0.2.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
+ "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "socket.io": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz",
+ "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=",
+ "dev": true,
+ "requires": {
+ "debug": "2.3.3",
+ "engine.io": "1.8.3",
+ "has-binary": "0.1.7",
+ "object-assign": "4.1.0",
+ "socket.io-adapter": "0.5.0",
+ "socket.io-client": "1.7.3",
+ "socket.io-parser": "2.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
+ "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=",
+ "dev": true
+ }
+ }
+ },
+ "socket.io-adapter": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz",
+ "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=",
+ "dev": true,
+ "requires": {
+ "debug": "2.3.3",
+ "socket.io-parser": "2.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ }
+ }
+ },
+ "socket.io-client": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz",
+ "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=",
+ "dev": true,
+ "requires": {
+ "backo2": "1.0.2",
+ "component-bind": "1.0.0",
+ "component-emitter": "1.2.1",
+ "debug": "2.3.3",
+ "engine.io-client": "1.8.3",
+ "has-binary": "0.1.7",
+ "indexof": "0.0.1",
+ "object-component": "0.0.3",
+ "parseuri": "0.0.5",
+ "socket.io-parser": "2.3.1",
+ "to-array": "0.1.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ }
+ }
+ },
+ "socket.io-parser": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz",
+ "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=",
+ "dev": true,
+ "requires": {
+ "component-emitter": "1.1.2",
+ "debug": "2.2.0",
+ "isarray": "0.0.1",
+ "json3": "3.3.2"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz",
+ "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "ms": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
+ "dev": true
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "source-map-resolve": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz",
+ "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==",
+ "dev": true,
+ "requires": {
+ "atob": "2.0.3",
+ "decode-uri-component": "0.2.0",
+ "resolve-url": "0.2.1",
+ "source-map-url": "0.4.0",
+ "urix": "0.1.0"
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "sparkles": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz",
+ "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+ "dev": true,
+ "requires": {
+ "spdx-license-ids": "1.2.2"
+ }
+ },
+ "spdx-expression-parse": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+ "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
+ "dev": true
+ },
+ "spdx-license-ids": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+ "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
+ "dev": true
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "3.0.2"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "dev": true,
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "stack-trace": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz",
+ "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=",
+ "dev": true
+ },
+ "standard": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/standard/-/standard-9.0.2.tgz",
+ "integrity": "sha1-m9O5RnSS4hKxkU14VTlD/5tI/Zk=",
+ "dev": true,
+ "requires": {
+ "eslint": "3.18.0",
+ "eslint-config-standard": "7.1.0",
+ "eslint-config-standard-jsx": "3.3.0",
+ "eslint-plugin-promise": "3.4.2",
+ "eslint-plugin-react": "6.9.0",
+ "eslint-plugin-standard": "2.0.1",
+ "standard-engine": "5.4.0"
+ }
+ },
+ "standard-engine": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-5.4.0.tgz",
+ "integrity": "sha1-4OhpWeoHhkJdM4PkDBv3DS+YVXk=",
+ "dev": true,
+ "requires": {
+ "deglob": "2.1.0",
+ "get-stdin": "5.0.1",
+ "home-or-tmp": "2.0.0",
+ "minimist": "1.2.0",
+ "pkg-conf": "2.1.0"
+ },
+ "dependencies": {
+ "get-stdin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
+ "dev": true
+ }
+ }
+ },
+ "standard-json": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/standard-json/-/standard-json-1.0.2.tgz",
+ "integrity": "sha1-gt6koUx4zZ4104zeS4isa2JZaiM=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.0"
+ }
+ },
+ "stat-mode": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz",
+ "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=",
+ "dev": true
+ },
+ "static-eval": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.0.tgz",
+ "integrity": "sha512-6flshd3F1Gwm+Ksxq463LtFd1liC77N/PX1FVVc3OzL3hAmo2fwHFbuArkcfi7s9rTNsLEhcRmXGFZhlgy40uw==",
+ "dev": true,
+ "requires": {
+ "escodegen": "1.8.1"
+ }
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "0.2.5",
+ "object-copy": "0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "static-module": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.1.1.tgz",
+ "integrity": "sha512-PPLCnxRl74wV38rG1T0rH8Fl2wIktTXFo7/varrZjtSGb/vndZIGkpe4HJVd8hoBYXRkRHW6hlCRAHvmDgrYQQ==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.0",
+ "duplexer2": "0.1.4",
+ "escodegen": "1.9.0",
+ "falafel": "2.1.0",
+ "has": "1.0.1",
+ "object-inspect": "1.4.1",
+ "quote-stream": "1.0.2",
+ "readable-stream": "2.3.4",
+ "shallow-copy": "0.0.1",
+ "static-eval": "2.0.0",
+ "through2": "2.0.3"
+ },
+ "dependencies": {
+ "duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "2.3.4"
+ }
+ },
+ "escodegen": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz",
+ "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==",
+ "dev": true,
+ "requires": {
+ "esprima": "3.1.3",
+ "estraverse": "4.2.0",
+ "esutils": "2.0.2",
+ "optionator": "0.8.2",
+ "source-map": "0.5.7"
+ }
+ },
+ "esprima": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+ "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
+ "dev": true
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
+ "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
+ "dev": true
+ },
+ "stream-consume": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz",
+ "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==",
+ "dev": true
+ },
+ "stream-counter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-1.0.0.tgz",
+ "integrity": "sha1-kc8lac5NxQYf6816yyY5SloRR1E=",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-bom": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz",
+ "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=",
+ "dev": true,
+ "requires": {
+ "first-chunk-stream": "1.0.0",
+ "is-utf8": "0.2.1"
+ }
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "4.0.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ },
+ "sver-compat": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
+ "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "svgdom": {
+ "version": "0.0.15",
+ "resolved": "https://registry.npmjs.org/svgdom/-/svgdom-0.0.15.tgz",
+ "integrity": "sha1-djlZYSQUjJ8eBlntNGgtN5s2dO4=",
+ "dev": true,
+ "requires": {
+ "fontkit": "1.7.7",
+ "gl-matrix": "2.4.0",
+ "image-size": "0.5.5",
+ "sax": "1.2.4"
+ }
+ },
+ "table": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
+ "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
+ "dev": true,
+ "requires": {
+ "ajv": "4.11.8",
+ "ajv-keywords": "1.5.1",
+ "chalk": "1.1.3",
+ "lodash": "4.17.5",
+ "slice-ansi": "0.0.4",
+ "string-width": "2.1.1"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "dev": true,
+ "requires": {
+ "co": "4.6.0",
+ "json-stable-stringify": "1.0.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ }
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "2.3.4",
+ "xtend": "4.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
+ "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "tildify": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz",
+ "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "1.0.2"
+ }
+ },
+ "time-stamp": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
+ "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
+ "dev": true
+ },
+ "tiny-inflate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.2.tgz",
+ "integrity": "sha1-k9nez/yIBb1X6uQxDwt0Xptvs6c=",
+ "dev": true
+ },
+ "tmp": {
+ "version": "0.0.31",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
+ "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "to-array": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+ "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
+ "dev": true
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "regex-not": "1.0.2",
+ "safe-regex": "1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+ "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+ "dev": true
+ },
+ "tryit": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
+ "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true,
+ "optional": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2"
+ }
+ },
+ "type-is": {
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "dev": true,
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "2.1.18"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "2.8.29",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+ "dev": true,
+ "requires": {
+ "source-map": "0.5.7",
+ "uglify-to-browserify": "1.0.2",
+ "yargs": "3.10.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+ "dev": true,
+ "requires": {
+ "center-align": "0.1.3",
+ "right-align": "0.1.3",
+ "wordwrap": "0.0.2"
+ }
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+ "dev": true,
+ "requires": {
+ "camelcase": "1.2.1",
+ "cliui": "2.1.0",
+ "decamelize": "1.2.0",
+ "window-size": "0.1.0"
+ }
+ }
+ }
+ },
+ "uglify-save-license": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/uglify-save-license/-/uglify-save-license-0.4.1.tgz",
+ "integrity": "sha1-lXJsF8xv0XHDYX479NjYKqjEzOE=",
+ "dev": true
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "dev": true,
+ "optional": true
+ },
+ "ultron": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
+ "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=",
+ "dev": true
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
+ "dev": true
+ },
+ "unicode-properties": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.1.0.tgz",
+ "integrity": "sha1-epbu9J91aC6mnSMV7smsQ//fAME=",
+ "dev": true,
+ "requires": {
+ "brfs": "1.4.4",
+ "unicode-trie": "0.3.1"
+ }
+ },
+ "unicode-trie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz",
+ "integrity": "sha1-1nHd3YkQGgi6w3tqUWEBBgIFIIU=",
+ "dev": true,
+ "requires": {
+ "pako": "0.2.9",
+ "tiny-inflate": "1.0.2"
+ }
+ },
+ "union-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "dev": true,
+ "requires": {
+ "arr-union": "3.1.0",
+ "get-value": "2.0.6",
+ "is-extendable": "0.1.1",
+ "set-value": "0.4.3"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "to-object-path": "0.3.0"
+ }
+ }
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+ "dev": true
+ },
+ "unique-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz",
+ "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "0.3.1",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "0.1.4",
+ "isobject": "2.1.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ }
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "use": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz",
+ "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=",
+ "dev": true,
+ "requires": {
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "lazy-cache": "2.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "user-home": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
+ "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=",
+ "dev": true
+ },
+ "useragent": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
+ "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "4.1.1",
+ "tmp": "0.0.31"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+ "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.1.2"
+ }
+ }
+ }
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.1"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
+ }
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+ "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
+ "dev": true
+ },
+ "v8flags": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz",
+ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=",
+ "dev": true,
+ "requires": {
+ "user-home": "1.1.1"
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "1.0.2",
+ "spdx-expression-parse": "1.0.4"
+ }
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "1.3.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "vinyl": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz",
+ "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=",
+ "dev": true,
+ "requires": {
+ "clone": "1.0.3",
+ "clone-stats": "0.0.1",
+ "replace-ext": "0.0.1"
+ }
+ },
+ "vinyl-bufferstream": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/vinyl-bufferstream/-/vinyl-bufferstream-1.0.1.tgz",
+ "integrity": "sha1-BTeGn1gO/6TKRay0dXnkuf5jCBo=",
+ "dev": true,
+ "requires": {
+ "bufferstreams": "1.0.1"
+ }
+ },
+ "vinyl-fs": {
+ "version": "0.3.14",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz",
+ "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=",
+ "dev": true,
+ "requires": {
+ "defaults": "1.0.3",
+ "glob-stream": "3.1.18",
+ "glob-watcher": "0.0.6",
+ "graceful-fs": "3.0.11",
+ "mkdirp": "0.5.1",
+ "strip-bom": "1.0.0",
+ "through2": "0.6.5",
+ "vinyl": "0.4.6"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
+ "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "through2": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
+ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.0.34",
+ "xtend": "4.0.1"
+ }
+ },
+ "vinyl": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
+ "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
+ "dev": true,
+ "requires": {
+ "clone": "0.2.0",
+ "clone-stats": "0.0.1"
+ }
+ }
+ }
+ },
+ "vinyl-sourcemaps-apply": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
+ "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
+ "dev": true,
+ "requires": {
+ "source-map": "0.5.7"
+ }
+ },
+ "void-elements": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+ "dev": true,
+ "requires": {
+ "isexe": "2.0.0"
+ }
+ },
+ "window-size": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
+ "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "wreck": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/wreck/-/wreck-6.3.0.tgz",
+ "integrity": "sha1-oTaXafB7u2LWo3gzanhx/Hc8dAs=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1",
+ "hoek": "2.16.3"
+ }
+ },
+ "write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+ "dev": true,
+ "requires": {
+ "mkdirp": "0.5.1"
+ }
+ },
+ "ws": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz",
+ "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=",
+ "dev": true,
+ "requires": {
+ "options": "0.0.6",
+ "ultron": "1.0.2"
+ }
+ },
+ "wtf-8": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz",
+ "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=",
+ "dev": true
+ },
+ "xmlhttprequest-ssl": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
+ "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "3.32.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
+ "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
+ "dev": true,
+ "requires": {
+ "camelcase": "2.1.1",
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "os-locale": "1.4.0",
+ "string-width": "1.0.2",
+ "window-size": "0.1.4",
+ "y18n": "3.2.1"
+ }
+ },
+ "yauzl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+ "dev": true,
+ "requires": {
+ "fd-slicer": "1.0.1"
+ }
+ },
+ "yeast": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+ "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
index 7853409..9cc9a1d 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,7 @@
"gulp-header": "^1.0.5",
"gulp-rename": "^1.2.0",
"gulp-size": "^2.1.0",
+ "gulp-standard": "^10.1.2",
"gulp-trimlines": "^1.0.0",
"gulp-uglify": "^2.0.0",
"gulp-wrap": "^0.13.0",
diff --git a/src/HtmlNode.js b/src/HtmlNode.js
index 38309e3..30cb4cf 100644
--- a/src/HtmlNode.js
+++ b/src/HtmlNode.js
@@ -1,25 +1,28 @@
+/* global createElement */
+
SVG.HtmlNode = SVG.invent({
- create: function(element) {
+ create: function (element) {
this.node = element
- }
+ },
-, extend: {
- add: function(element, i) {
+ extend: {
+ add: function (element, i) {
element = createElement(element)
- if(element instanceof SVG.Nested) {
+ if (element instanceof SVG.Nested) {
element = new SVG.Doc(element.node)
element.setData(JSON.parse(element.node.getAttribute('svgjs:data')) || {})
}
- if (i == null)
+ if (i === null) {
this.node.appendChild(element.node)
- else if (element.node != this.node.children[i])
+ } else if (element.node !== this.node.children[i]) {
this.node.insertBefore(element.node, this.node.children[i])
+ }
return this
- }
+ },
- , put: function(element, i) {
+ put: function (element, i) {
this.add(element, i)
return element
}
diff --git a/src/arrange.js b/src/arrange.js
index 15d3d3c..a908143 100644
--- a/src/arrange.js
+++ b/src/arrange.js
@@ -3,83 +3,95 @@
//
SVG.extend(SVG.Element, {
// Get all siblings, including myself
- siblings: function() {
+ siblings: function () {
return this.parent().children()
- }
+ },
+
// Get the curent position siblings
-, position: function() {
+ position: function () {
return this.parent().index(this)
- }
+ },
+
// Get the next element (will return null if there is none)
-, next: function() {
+ next: function () {
return this.siblings()[this.position() + 1]
- }
+ },
+
// Get the next element (will return null if there is none)
-, prev: function() {
+ prev: function () {
return this.siblings()[this.position() - 1]
- }
+ },
+
// Send given element one step forward
-, forward: function() {
+ forward: function () {
var i = this.position() + 1
- , p = this.parent()
+ var p = this.parent()
// move node one step forward
p.removeElement(this).add(this, i)
// make sure defs node is always at the top
- if (p instanceof SVG.Doc)
+ if (p instanceof SVG.Doc) {
p.node.appendChild(p.defs().node)
+ }
return this
- }
+ },
+
// Send given element one step backward
-, backward: function() {
+ backward: function () {
var i = this.position()
-
- if (i > 0)
+
+ if (i > 0) {
this.parent().removeElement(this).add(this, i - 1)
+ }
return this
- }
+ },
+
// Send given element all the way to the front
-, front: function() {
+ front: function () {
var p = this.parent()
// Move node forward
p.node.appendChild(this.node)
// Make sure defs node is always at the top
- if (p instanceof SVG.Doc)
+ if (p instanceof SVG.Doc) {
p.node.appendChild(p.defs().node)
+ }
return this
- }
+ },
+
// Send given element all the way to the back
-, back: function() {
- if (this.position() > 0)
+ back: function () {
+ if (this.position() > 0) {
this.parent().removeElement(this).add(this, 0)
-
+ }
+
return this
- }
+ },
+
// Inserts a given element before the targeted element
-, before: function(element) {
+ before: function (element) {
element.remove()
var i = this.position()
-
+
this.parent().add(element, i)
return this
- }
+ },
+
// Insters a given element after the targeted element
-, after: function(element) {
+ after: function (element) {
element.remove()
-
+
var i = this.position()
-
+
this.parent().add(element, i + 1)
return this
}
-
-}) \ No newline at end of file
+})
diff --git a/src/array.js b/src/array.js
index b532296..ca51d8e 100644
--- a/src/array.js
+++ b/src/array.js
@@ -1,10 +1,13 @@
+/* global arrayClone */
+
// Module for array conversion
-SVG.Array = function(array, fallback) {
+SVG.Array = function (array, fallback) {
array = (array || []).valueOf()
// if array is empty and fallback is provided, use fallback
- if (array.length == 0 && fallback)
+ if (array.length === 0 && fallback) {
array = fallback.valueOf()
+ }
// parse array
this.value = this.parse(array)
@@ -12,69 +15,75 @@ SVG.Array = function(array, fallback) {
SVG.extend(SVG.Array, {
// Make array morphable
- morph: function(array) {
+ morph: function (array) {
this.destination = this.parse(array)
// normalize length of arrays
- if (this.value.length != this.destination.length) {
- var lastValue = this.value[this.value.length - 1]
- , lastDestination = this.destination[this.destination.length - 1]
+ if (this.value.length !== this.destination.length) {
+ var lastValue = this.value[this.value.length - 1]
+ var lastDestination = this.destination[this.destination.length - 1]
- while(this.value.length > this.destination.length)
+ while (this.value.length > this.destination.length) {
this.destination.push(lastDestination)
- while(this.value.length < this.destination.length)
+ }
+ while (this.value.length < this.destination.length) {
this.value.push(lastValue)
+ }
}
return this
- }
+ },
// Clean up any duplicate points
-, settle: function() {
+ settle: function () {
// find all unique values
- for (var i = 0, il = this.value.length, seen = []; i < il; i++)
- if (seen.indexOf(this.value[i]) == -1)
+ for (var i = 0, il = this.value.length, seen = []; i < il; i++) {
+ if (seen.indexOf(this.value[i]) === -1) {
seen.push(this.value[i])
+ }
+ }
// set new value
- return this.value = seen
- }
+ this.value = seen
+ return seen
+ },
// Get morphed array at given position
-, at: function(pos) {
+ at: function (pos) {
// make sure a destination is defined
if (!this.destination) return this
// generate morphed array
- for (var i = 0, il = this.value.length, array = []; i < il; i++)
+ for (var i = 0, il = this.value.length, array = []; i < il; i++) {
array.push(this.value[i] + (this.destination[i] - this.value[i]) * pos)
+ }
return new SVG.Array(array)
- }
+ },
// Convert array to string
-, toString: function() {
+ toString: function () {
return this.value.join(' ')
- }
+ },
// Real value
-, valueOf: function() {
+ valueOf: function () {
return this.value
- }
+ },
// Parse whitespace separated string
-, parse: function(array) {
+ parse: function (array) {
array = array.valueOf()
// if already is an array, no need to parse it
if (Array.isArray(array)) return array
return array.trim().split(SVG.regex.delimiter).map(parseFloat)
- }
+ },
// Reverse array
-, reverse: function() {
+ reverse: function () {
this.value.reverse()
return this
- }
-, clone: function() {
+ },
+ clone: function () {
var clone = new this.constructor()
- clone.value = array_clone(this.value)
+ clone.value = arrayClone(this.value)
return clone
}
-}) \ No newline at end of file
+})
diff --git a/src/attr.js b/src/attr.js
index bc09fe3..19c7525 100644
--- a/src/attr.js
+++ b/src/attr.js
@@ -1,74 +1,72 @@
SVG.extend(SVG.Element, {
// Set svg element attribute
- attr: function(a, v, n) {
+ attr: function (a, v, n) {
// act as full getter
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.isNumber.test(v[n].nodeValue) ? parseFloat(v[n].nodeValue) : v[n].nodeValue
-
+ for (n = v.length - 1; n >= 0; n--) {
+ a[v[n].nodeName] = SVG.regex.isNumber.test(v[n].nodeValue)
+ ? parseFloat(v[n].nodeValue)
+ : v[n].nodeValue
+ }
return a
-
- } else if (typeof a == 'object') {
+ } 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)
-
+ this.node.removeAttribute(a)
} else if (v == null) {
// act as a getter if the first and only argument is not an object
v = this.node.getAttribute(a)
- return v == null ?
- SVG.defaults.attrs[a] :
- SVG.regex.isNumber.test(v) ?
- parseFloat(v) : v
-
+ return v == null ? SVG.defaults.attrs[a]
+ : SVG.regex.isNumber.test(v) ? parseFloat(v)
+ : v
} else {
-
// convert image fill and stroke to patterns
- if (a == 'fill' || a == 'stroke') {
- if (SVG.regex.isImage.test(v))
+ if (a === 'fill' || a === 'stroke') {
+ if (SVG.regex.isImage.test(v)) {
v = this.doc().defs().image(v)
+ }
- if (v instanceof SVG.Image)
- v = this.doc().defs().pattern(0, 0, function() {
+ if (v instanceof SVG.Image) {
+ v = this.doc().defs().pattern(0, 0, function () {
this.add(v)
})
+ }
}
-
+
// ensure correct numeric values (also accepts NaN and Infinity)
- if (typeof v === 'number')
+ if (typeof v === 'number') {
v = new SVG.Number(v)
-
- // ensure full hex color
- else if (SVG.Color.isColor(v))
+ } else if (SVG.Color.isColor(v)) {
+ // ensure full hex color
v = new SVG.Color(v)
-
- // parse array values
- else if (Array.isArray(v))
+ } else if (Array.isArray(v)) {
+ // parse array values
v = new SVG.Array(v)
+ }
// if the passed attribute is leading...
- if (a == 'leading') {
+ if (a === 'leading') {
// ... call the leading method instead
- if (this.leading)
+ if (this.leading) {
this.leading(v)
+ }
} else {
// set given attribute on node
- typeof n === 'string' ?
- this.node.setAttributeNS(n, a, v.toString()) :
- this.node.setAttribute(a, v.toString())
+ typeof n === 'string' ? this.node.setAttributeNS(n, a, v.toString())
+ : this.node.setAttribute(a, v.toString())
}
-
+
// rebuild if required
- if (this.rebuild && (a == 'font-size' || a == 'x'))
+ if (this.rebuild && (a === 'font-size' || a === 'x')) {
this.rebuild(a, v)
+ }
}
-
+
return this
}
-}) \ No newline at end of file
+})
diff --git a/src/bare.js b/src/bare.js
index 5ac4173..44b762c 100644
--- a/src/bare.js
+++ b/src/bare.js
@@ -1,27 +1,31 @@
SVG.Bare = SVG.invent({
// Initialize
- create: function(element, inherit) {
+ create: function (element, inherit) {
// construct element
- this.constructor.call(this, SVG.create(element))
+ this.constructor(SVG.create(element))
// inherit custom methods
- if (inherit)
- for (var method in inherit.prototype)
- if (typeof inherit.prototype[method] === 'function')
+ if (inherit) {
+ for (var method in inherit.prototype) {
+ if (typeof inherit.prototype[method] === 'function') {
this[method] = inherit.prototype[method]
- }
+ }
+ }
+ }
+ },
// Inherit from
-, inherit: SVG.Element
+ inherit: SVG.Element,
// Add methods
-, extend: {
+ extend: {
// Insert some plain text
- words: function(text) {
+ words: function (text) {
// remove contents
- while (this.node.hasChildNodes())
+ while (this.node.hasChildNodes()) {
this.node.removeChild(this.node.lastChild)
+ }
// create text node
this.node.appendChild(document.createTextNode(text))
@@ -31,10 +35,9 @@ SVG.Bare = SVG.invent({
}
})
-
SVG.extend(SVG.Parent, {
// Create an element that is not described by SVG.js
- element: function(element, inherit) {
+ element: function (element, inherit) {
return this.put(new SVG.Bare(element, inherit))
}
})
diff --git a/src/boxes.js b/src/boxes.js
index eb58c06..a5ca1e8 100644
--- a/src/boxes.js
+++ b/src/boxes.js
@@ -1,15 +1,14 @@
+/* globals fullBox, domContains, isNulledBox, Exception */
+
SVG.Box = SVG.invent({
- create: function(source) {
- var base = [0,0,0,0]
- source = typeof source === 'string' ?
- source.split(SVG.regex.delimiter).map(parseFloat) :
- Array.isArray(source) ?
- source :
- typeof source == 'object' ?
- [source.left != null ? source.left : source.x, source.top != null ? source.top : source.y, source.width, source.height] :
- arguments.length == 4 ?
- [].slice.call(arguments) :
- base
+ create: function (source) {
+ var base = [0, 0, 0, 0]
+ source = typeof source === 'string' ? source.split(SVG.regex.delimiter).map(parseFloat)
+ : Array.isArray(source) ? source
+ : typeof source === 'object' ? [source.left != null ? source.left
+ : source.x, source.top != null ? source.top : source.y, source.width, source.height]
+ : arguments.length === 4 ? [].slice.call(arguments)
+ : base
this.x = source[0]
this.y = source[1]
@@ -18,22 +17,25 @@ SVG.Box = SVG.invent({
// add center, right, bottom...
fullBox(this)
- }
-, extend: {
+ },
+ extend: {
// Merge rect box with another, return a new instance
- merge: function(box) {
+ merge: function (box) {
var x = Math.min(this.x, box.x)
- , y = Math.min(this.y, box.y)
+ var y = Math.min(this.y, box.y)
return new SVG.Box(
x, y,
- Math.max(this.x + this.width, box.x + box.width) - x,
+ Math.max(this.x + this.width, box.x + box.width) - x,
Math.max(this.y + this.height, box.y + box.height) - y
)
- }
+ },
- , transform: function(m) {
- var xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, p, bbox
+ transform: function (m) {
+ var xMin = Infinity
+ var xMax = -Infinity
+ var yMin = Infinity
+ var yMax = -Infinity
var pts = [
new SVG.Point(this.x, this.y),
@@ -42,37 +44,37 @@ SVG.Box = SVG.invent({
new SVG.Point(this.x2, this.y2)
]
- pts.forEach(function(p) {
+ pts.forEach(function (p) {
p = p.transform(m)
- xMin = Math.min(xMin,p.x)
- xMax = Math.max(xMax,p.x)
- yMin = Math.min(yMin,p.y)
- yMax = Math.max(yMax,p.y)
+ xMin = Math.min(xMin, p.x)
+ xMax = Math.max(xMax, p.x)
+ yMin = Math.min(yMin, p.y)
+ yMax = Math.max(yMax, p.y)
})
return new SVG.Box(
xMin, yMin,
- xMax-xMin,
- yMax-yMin
+ xMax - xMin,
+ yMax - yMin
)
- }
+ },
- , addOffset: function() {
+ addOffset: function () {
// offset by window scroll position, because getBoundingClientRect changes when window is scrolled
this.x += window.pageXOffset
this.y += window.pageYOffset
return this
- }
- , toString: function() {
+ },
+ toString: function () {
return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height
- }
- , morph: function(x, y, width, height){
+ },
+ morph: function (x, y, width, height) {
this.destination = new SVG.Box(x, y, width, height)
return this
- }
+ },
- , at: function(pos) {
- if(!this.destination) return this
+ at: function (pos) {
+ if (!this.destination) return this
return new SVG.Box(
this.x + (this.destination.x - this.x) * pos
@@ -80,46 +82,45 @@ SVG.Box = SVG.invent({
, this.width + (this.destination.width - this.width) * pos
, this.height + (this.destination.height - this.height) * pos
)
-
}
- }
+ },
// Define Parent
-, parent: SVG.Element
+ parent: SVG.Element,
// Constructor
-, construct: {
+ construct: {
// Get bounding box
- bbox: function() {
+ bbox: function () {
var box
try {
// find native bbox
box = this.node.getBBox()
- if(isNulledBox(box) && !domContains(this.node)) {
+ if (isNulledBox(box) && !domContains(this.node)) {
throw new Exception('Element not in the dom')
}
- } catch(e) {
+ } catch (e) {
try {
var clone = this.clone(SVG.parser().svg).show()
box = clone.node.getBBox()
clone.remove()
- } catch(e) {
+ } catch (e) {
console.warn('Getting a bounding box of this element is not possible')
}
}
return new SVG.Box(box)
- }
+ },
- , rbox: function(el) {
+ rbox: function (el) {
// IE11 throws an error when element not in dom
- try{
+ try {
var box = new SVG.Box(this.node.getBoundingClientRect())
if (el) return box.transform(el.screenCTM().inverse())
return box.addOffset()
- } catch(e) {
+ } catch (e) {
return new SVG.Box()
}
}
@@ -127,9 +128,9 @@ SVG.Box = SVG.invent({
})
SVG.extend([SVG.Doc, SVG.Nested, SVG.Symbol, SVG.Image, SVG.Pattern, SVG.Marker, SVG.ForeignObject, SVG.View], {
- viewbox: function(x, y, width, height) {
+ viewbox: function (x, y, width, height) {
// act as getter
- if(x == null) return new SVG.Box(this.attr('viewBox'))
+ if (x == null) return new SVG.Box(this.attr('viewBox'))
// act as setter
return this.attr('viewBox', new SVG.Box(x, y, width, height))
diff --git a/src/clip.js b/src/clip.js
index b43712e..63fff74 100644
--- a/src/clip.js
+++ b/src/clip.js
@@ -1,33 +1,33 @@
SVG.ClipPath = SVG.invent({
// Initialize node
- create: 'clipPath'
+ create: 'clipPath',
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
// Add class methods
-, extend: {
+ extend: {
// Unclip all clipped elements and remove itself
- remove: function() {
+ remove: function () {
// unclip all targets
- this.targets().forEach(function(el) {
+ this.targets().forEach(function (el) {
el.unclip()
})
// remove clipPath from parent
return SVG.Element.prototype.remove.call(this)
+ },
+
+ targets: function () {
+ return SVG.select('svg [clip-path*="' + this.id() + '"]')
}
-
- , targets: function() {
- return SVG.select('svg [clip-path*="' +this.id() +'"]')
- }
- }
+ },
// Add parent method
-, construct: {
+ construct: {
// Create clipping element
- clip: function() {
- return this.defs().put(new SVG.ClipPath)
+ clip: function () {
+ return this.defs().put(new SVG.ClipPath())
}
}
})
@@ -35,19 +35,19 @@ SVG.ClipPath = SVG.invent({
//
SVG.extend(SVG.Element, {
// Distribute clipPath to svg element
- clipWith: function(element) {
+ clipWith: function (element) {
// use given clip or create a new one
var clipper = element instanceof SVG.ClipPath ? element : this.parent().clip().add(element)
// apply mask
return this.attr('clip-path', 'url("#' + clipper.id() + '")')
- }
+ },
// Unclip element
-, unclip: function() {
+ unclip: function () {
return this.attr('clip-path', null)
- }
-, clipper: function() {
+ },
+ clipper: function () {
return this.reference('clip-path')
}
-}) \ No newline at end of file
+})
diff --git a/src/color.js b/src/color.js
index 9d77d4e..8f47f70 100644
--- a/src/color.js
+++ b/src/color.js
@@ -1,108 +1,105 @@
+/* globals fullHex, compToHex */
+
// Module for color convertions
-SVG.Color = function(color) {
+SVG.Color = function (color) {
var match
-
- // initialize defaults
+
+ // initialize defaults
this.r = 0
this.g = 0
this.b = 0
-
- if(!color) return
-
- // parse color
+
+ if (!color) return
+
+ // parse color
if (typeof color === 'string') {
if (SVG.regex.isRgb.test(color)) {
- // get rgb values
- match = SVG.regex.rgb.exec(color.replace(SVG.regex.whitespace,''))
-
- // parse numeric values
+ // get rgb values
+ match = SVG.regex.rgb.exec(color.replace(SVG.regex.whitespace, ''))
+
+ // parse numeric values
this.r = parseInt(match[1])
this.g = parseInt(match[2])
this.b = parseInt(match[3])
-
} else if (SVG.regex.isHex.test(color)) {
- // get hex values
+ // get hex values
match = SVG.regex.hex.exec(fullHex(color))
- // parse numeric values
+ // parse numeric values
this.r = parseInt(match[1], 16)
this.g = parseInt(match[2], 16)
this.b = parseInt(match[3], 16)
-
}
-
} else if (typeof color === 'object') {
this.r = color.r
this.g = color.g
this.b = color.b
-
}
-
}
SVG.extend(SVG.Color, {
// Default to hex conversion
- toString: function() {
+ toString: function () {
return this.toHex()
- }
+ },
// Build hex value
-, toHex: function() {
- return '#'
- + compToHex(this.r)
- + compToHex(this.g)
- + compToHex(this.b)
- }
+ toHex: function () {
+ return '#' +
+ compToHex(this.r) +
+ compToHex(this.g) +
+ compToHex(this.b)
+ },
// Build rgb value
-, toRgb: function() {
+ toRgb: function () {
return 'rgb(' + [this.r, this.g, this.b].join() + ')'
- }
+ },
// Calculate true brightness
-, brightness: function() {
- return (this.r / 255 * 0.30)
- + (this.g / 255 * 0.59)
- + (this.b / 255 * 0.11)
- }
+ brightness: function () {
+ return (this.r / 255 * 0.30) +
+ (this.g / 255 * 0.59) +
+ (this.b / 255 * 0.11)
+ },
// Make color morphable
-, morph: function(color) {
+ morph: function (color) {
this.destination = new SVG.Color(color)
return this
- }
+ },
// Get morphed color at given position
-, at: function(pos) {
- // make sure a destination is defined
+ at: function (pos) {
+ // make sure a destination is defined
if (!this.destination) return this
- // normalise pos
+ // normalise pos
pos = pos < 0 ? 0 : pos > 1 ? 1 : pos
- // generate morphed color
+ // generate morphed color
return new SVG.Color({
- r: ~~(this.r + (this.destination.r - this.r) * pos)
- , g: ~~(this.g + (this.destination.g - this.g) * pos)
- , b: ~~(this.b + (this.destination.b - this.b) * pos)
+ r: ~~(this.r + (this.destination.r - this.r) * pos),
+ g: ~~(this.g + (this.destination.g - this.g) * pos),
+ b: ~~(this.b + (this.destination.b - this.b) * pos)
})
}
-
+
})
// Testers
// Test if given value is a color string
-SVG.Color.test = function(color) {
+SVG.Color.test = function (color) {
color += ''
- return SVG.regex.isHex.test(color)
- || SVG.regex.isRgb.test(color)
+ return SVG.regex.isHex.test(color) ||
+ SVG.regex.isRgb.test(color)
}
// Test if given value is a rgb object
-SVG.Color.isRgb = function(color) {
- return color && typeof color.r == 'number'
- && typeof color.g == 'number'
- && typeof color.b == 'number'
+SVG.Color.isRgb = function (color) {
+ return color && typeof color.r === 'number' &&
+ typeof color.g === 'number' &&
+ typeof color.b === 'number'
}
// Test if given value is a color
-SVG.Color.isColor = function(color) {
+SVG.Color.isColor = function (color) {
return SVG.Color.isRgb(color) || SVG.Color.test(color)
-} \ No newline at end of file
+}
diff --git a/src/container.js b/src/container.js
index e620041..90e8f26 100644
--- a/src/container.js
+++ b/src/container.js
@@ -1,10 +1,9 @@
SVG.Container = SVG.invent({
// Initialize node
- create: function(node) {
- this.constructor.call(this, node)
- }
+ create: function (node) {
+ this.constructor(node)
+ },
// Inherit from
-, inherit: SVG.Parent
-
-}) \ No newline at end of file
+ inherit: SVG.Parent
+})
diff --git a/src/css.js b/src/css.js
index 3ecb2b9..c549bd5 100644
--- a/src/css.js
+++ b/src/css.js
@@ -1,10 +1,13 @@
+/* global camelCase */
+
SVG.extend(SVG.Element, {
// Dynamic style generator
- css: function(s, v) {
- var t, i, ret = {}
- if (arguments.length == 0) {
+ css: function (s, v) {
+ var ret = {}
+ var t, i
+ if (arguments.length === 0) {
// get full style as object
- this.node.style.cssText.split(/\s*;\s*/).filter(function(el) { return !!el.length }).forEach(function(el) {
+ this.node.style.cssText.split(/\s*;\s*/).filter(function (el) { return !!el.length }).forEach(function (el) {
t = el.split(/\s*:\s*/)
ret[t[0]] = t[1]
})
@@ -13,21 +16,21 @@ SVG.extend(SVG.Element, {
if (arguments.length < 2) {
// get style properties in the array
- if(Array.isArray(s)) {
- for(i = s.length; i--;) {
+ if (Array.isArray(s)) {
+ for (i = s.length; i--;) {
ret[camelCase(s[i])] = this.node.style[camelCase(s[i])]
}
return ret
}
// get style for property
- if(typeof s == 'string') {
+ if (typeof s === 'string') {
return this.node.style[camelCase(s)]
}
// set styles in object
- if(typeof s == 'object') {
- for(i in s) {
+ if (typeof s === 'object') {
+ for (i in s) {
// set empty string if null/undefined/'' was given
this.node.style[camelCase(i)] = (s[i] == null || SVG.regex.isBlank.test(s[i])) ? '' : s[i]
}
@@ -35,7 +38,7 @@ SVG.extend(SVG.Element, {
}
// set style for property
- if (arguments.length == 2) {
+ if (arguments.length === 2) {
this.node.style[camelCase(s)] = (v == null || SVG.regex.isBlank.test(v)) ? '' : v
}
diff --git a/src/data.js b/src/data.js
index cefa21c..f7fcd55 100644
--- a/src/data.js
+++ b/src/data.js
@@ -1,29 +1,25 @@
SVG.extend(SVG.Element, {
// Store data values on svg nodes
- data: function(a, v, r) {
- if (typeof a == 'object') {
- for (v in a)
+ data: function (a, v, r) {
+ if (typeof a === 'object') {
+ for (v in a) {
this.data(v, a[v])
-
+ }
} else if (arguments.length < 2) {
try {
return JSON.parse(this.attr('data-' + a))
- } catch(e) {
+ } catch (e) {
return this.attr('data-' + a)
}
-
} else {
- this.attr(
- 'data-' + a
- , v === null ?
- null :
- r === true || typeof v === 'string' || typeof v === 'number' ?
- v :
- JSON.stringify(v)
+ this.attr('data-' + a,
+ v === null ? null
+ : r === true || typeof v === 'string' || typeof v === 'number' ? v
+ : JSON.stringify(v)
)
}
-
+
return this
}
-}) \ No newline at end of file
+})
diff --git a/src/default.js b/src/default.js
index d371ca0..c77b028 100644
--- a/src/default.js
+++ b/src/default.js
@@ -1,36 +1,42 @@
SVG.defaults = {
+
// Default attribute values
attrs: {
- // fill and stroke
- 'fill-opacity': 1
- , 'stroke-opacity': 1
- , 'stroke-width': 0
- , 'stroke-linejoin': 'miter'
- , 'stroke-linecap': 'butt'
- , fill: '#000000'
- , stroke: '#000000'
- , opacity: 1
- // position
- , x: 0
- , y: 0
- , cx: 0
- , cy: 0
- // size
- , width: 0
- , height: 0
- // radius
- , r: 0
- , rx: 0
- , ry: 0
- // gradient
- , offset: 0
- , 'stop-opacity': 1
- , 'stop-color': '#000000'
- // text
- , 'font-size': 16
- , 'font-family': 'Helvetica, Arial, sans-serif'
- , 'text-anchor': 'start'
+
+ // fill and stroke
+ 'fill-opacity': 1,
+ 'stroke-opacity': 1,
+ 'stroke-width': 0,
+ 'stroke-linejoin': 'miter',
+ 'stroke-linecap': 'butt',
+ fill: '#000000',
+ stroke: '#000000',
+ opacity: 1,
+
+ // position
+ x: 0,
+ y: 0,
+ cx: 0,
+ cy: 0,
+
+ // size
+ width: 0,
+ height: 0,
+
+ // radius
+ r: 0,
+ rx: 0,
+ ry: 0,
+
+ // gradient
+ offset: 0,
+ 'stop-opacity': 1,
+ 'stop-color': '#000000',
+
+ // text
+ 'font-size': 16,
+ 'font-family': 'Helvetica, Arial, sans-serif',
+ 'text-anchor': 'start'
}
-
-} \ No newline at end of file
+}
diff --git a/src/defs.js b/src/defs.js
index ba96869..3d6ebb9 100644
--- a/src/defs.js
+++ b/src/defs.js
@@ -1,7 +1,7 @@
SVG.Defs = SVG.invent({
// Initialize node
- create: 'defs'
+ create: 'defs',
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container
})
diff --git a/src/doc.js b/src/doc.js
index 7cdd6be..2097747 100644
--- a/src/doc.js
+++ b/src/doc.js
@@ -1,47 +1,48 @@
SVG.Doc = SVG.invent({
// Initialize node
- create: function(node) {
- this.constructor.call(this, node || SVG.create('svg'))
+ create: function (node) {
+ this.constructor(node || SVG.create('svg'))
// set svg element attributes and ensure defs node
this.namespace().defs()
- }
+ },
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
// Add class methods
-, extend: {
+ extend: {
// Add namespaces
- namespace: function() {
+ namespace: function () {
return this
.attr({ xmlns: SVG.ns, version: '1.1' })
.attr('xmlns:xlink', SVG.xlink, SVG.xmlns)
.attr('xmlns:svgjs', SVG.svgjs, SVG.xmlns)
- }
+ },
// Creates and returns defs element
- , defs: function() {
+ defs: function () {
return SVG.adopt(this.node.getElementsByTagName('defs')[0]) || this.put(new SVG.Defs())
- }
+ },
// custom parent method
- , parent: function() {
- return this.node.parentNode.nodeName == '#document' ? null : this.node.parentNode
- }
+ parent: function () {
+ return this.node.parentNode.nodeName === '#document' ? null : this.node.parentNode
+ },
// Removes the doc from the DOM
- , remove: function() {
- if(this.parent()) {
+ remove: function () {
+ if (this.parent()) {
this.parent().removeChild(this.node)
}
return this
- }
- , clear: function() {
+ },
+ clear: function () {
// remove children
- while(this.node.hasChildNodes())
+ while (this.node.hasChildNodes()) {
this.node.removeChild(this.node.lastChild)
+ }
return this
- }
- , toNested: function() {
+ },
+ toNested: function () {
var el = SVG.create('svg')
this.node.instance = null
el.appendChild(this.node)
diff --git a/src/element.js b/src/element.js
index c9b3fd7..eca535b 100644
--- a/src/element.js
+++ b/src/element.js
@@ -1,7 +1,8 @@
+/* global proportionalSize, assignNewId, createElement, matches, is */
SVG.Element = SVG.invent({
// Initialize node
- create: function(node) {
+ create: function (node) {
// last fired event on node
this._event = null
@@ -9,61 +10,71 @@ SVG.Element = SVG.invent({
this.dom = {}
// create circular reference
- if (this.node = node) {
+ this.node = node
+ if (this.node) {
this.type = node.nodeName
this.node.instance = this
- if(node.hasAttribute('svgjs:data')) {
+ if (node.hasAttribute('svgjs:data')) {
// pull svgjs data from the dom (getAttributeNS doesn't work in html5)
this.setData(JSON.parse(node.getAttribute('svgjs:data')) || {})
}
}
- }
+ },
// Add class methods
-, extend: {
+ extend: {
// Move over x-axis
- x: function(x) {
+ x: function (x) {
return this.attr('x', x)
- }
+ },
+
// Move over y-axis
- , y: function(y) {
+ y: function (y) {
return this.attr('y', y)
- }
+ },
+
// Move by center over x-axis
- , cx: function(x) {
+ 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) {
+ 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) {
+ move: function (x, y) {
return this.x(x).y(y)
- }
+ },
+
// Move element by its center
- , center: function(x, y) {
+ center: function (x, y) {
return this.cx(x).cy(y)
- }
+ },
+
// Set width of element
- , width: function(width) {
+ width: function (width) {
return this.attr('width', width)
- }
+ },
+
// Set height of element
- , height: function(height) {
+ height: function (height) {
return this.attr('height', height)
- }
+ },
+
// Set element size to given width and height
- , size: function(width, height) {
+ size: function (width, height) {
var p = proportionalSize(this, width, height)
return this
.width(new SVG.Number(p.width))
.height(new SVG.Number(p.height))
- }
+ },
+
// Clone element
- , clone: function(parent) {
+ clone: function (parent) {
// write dom data to the dom so the clone can pickup the data
this.writeDataToDom()
@@ -71,79 +82,90 @@ SVG.Element = SVG.invent({
var clone = assignNewId(this.node.cloneNode(true))
// insert the clone in the given parent or after myself
- if(parent) parent.add(clone)
+ if (parent) parent.add(clone)
else this.after(clone)
return clone
- }
+ },
+
// Remove element
- , remove: function() {
- if (this.parent())
- this.parent().removeElement(this)
+ remove: function () {
+ if (this.parent()) { this.parent().removeElement(this) }
return this
- }
+ },
+
// Replace element
- , replace: function(element) {
+ replace: function (element) {
this.after(element).remove()
return element
- }
+ },
+
// Add element to given container and return self
- , addTo: function(parent) {
+ addTo: function (parent) {
return createElement(parent).put(this)
- }
+ },
+
// Add element to given container and return container
- , putIn: function(parent) {
+ putIn: function (parent) {
return createElement(parent).add(this)
- }
+ },
+
// Get / set id
- , id: function(id) {
+ id: function (id) {
// generate new id if no id set
- if(typeof id == 'undefined' && !this.node.id) {
+ if (typeof id === 'undefined' && !this.node.id) {
this.node.id = SVG.eid(this.type)
}
// dont't set directly width this.node.id to make `null` work correctly
return this.attr('id', id)
- }
+ },
+
// Checks whether the given point inside the bounding box of the element
- , inside: function(x, y) {
+ 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
- }
+ return x > box.x &&
+ y > box.y &&
+ x < box.x + box.width &&
+ y < box.y + box.height
+ },
+
// Show element
- , show: function() {
+ show: function () {
return this.css('display', '')
- }
+ },
+
// Hide element
- , hide: function() {
+ hide: function () {
return this.css('display', 'none')
- }
+ },
+
// Is element visible?
- , visible: function() {
- return this.css('display') != 'none'
- }
+ visible: function () {
+ return this.css('display') !== 'none'
+ },
+
// Return id on string conversion
- , toString: function() {
+ toString: function () {
return this.id()
- }
+ },
+
// Return array of classes on the node
- , classes: function() {
+ classes: function () {
var attr = this.attr('class')
-
return attr == null ? [] : attr.trim().split(SVG.regex.delimiter)
- }
+ },
+
// Return true if class exists on the node, false otherwise
- , hasClass: function(name) {
- return this.classes().indexOf(name) != -1
- }
+ hasClass: function (name) {
+ return this.classes().indexOf(name) !== -1
+ },
+
// Add class to the node
- , addClass: function(name) {
+ addClass: function (name) {
if (!this.hasClass(name)) {
var array = this.classes()
array.push(name)
@@ -151,86 +173,96 @@ SVG.Element = SVG.invent({
}
return this
- }
+ },
+
// Remove class from the node
- , removeClass: function(name) {
+ removeClass: function (name) {
if (this.hasClass(name)) {
- this.attr('class', this.classes().filter(function(c) {
- return c != name
+ this.attr('class', this.classes().filter(function (c) {
+ return c !== name
}).join(' '))
}
return this
- }
+ },
+
// Toggle the presence of a class on the node
- , toggleClass: function(name) {
+ toggleClass: function (name) {
return this.hasClass(name) ? this.removeClass(name) : this.addClass(name)
- }
+ },
+
// Get referenced element form attribute value
- , reference: function(attr) {
+ reference: function (attr) {
return SVG.get(this.attr(attr))
- }
+ },
+
// Returns the parent element instance
- , parent: function(type) {
+ parent: function (type) {
var parent = this
// check for parent
- if(!parent.node.parentNode) return null
+ if (!parent.node.parentNode) return null
// get parent element
parent = SVG.adopt(parent.node.parentNode)
- if(!type) return parent
+ if (!type) return parent
// loop trough ancestors if type is given
- while(parent && parent.node instanceof window.SVGElement){
- if(typeof type === 'string' ? parent.matches(type) : parent instanceof type) return parent
+ while (parent && parent.node instanceof window.SVGElement) {
+ if (typeof type === 'string' ? parent.matches(type) : parent instanceof type) return parent
parent = SVG.adopt(parent.node.parentNode)
}
- }
+ },
+
// Get parent document
- , doc: function() {
+ doc: function () {
return this instanceof SVG.Doc ? this : this.parent(SVG.Doc)
- }
- , // Get defs
- defs: function() {
+ },
+
+ // Get defs
+ defs: function () {
return this.doc().defs()
- }
+ },
+
// return array of all ancestors of given type up to the root svg
- , parents: function(type) {
- var parents = [], parent = this
+ parents: function (type) {
+ var parents = []
+ var parent = this
- do{
+ do {
parent = parent.parent(type)
- if(!parent || !parent.node) break
+ if (!parent || !parent.node) break
parents.push(parent)
- } while(parent.parent)
+ } while (parent.parent)
return parents
- }
+ },
+
// matches the element vs a css selector
- , matches: function(selector){
+ matches: function (selector) {
return matches(this.node, selector)
- }
+ },
+
// Returns the svg node to call native svg methods on it
- , native: function() {
+ native: function () {
return this.node
- }
+ },
+
// Import raw svg
- , svg: function(svg) {
+ svg: function (svg) {
var well, len
// act as a setter if svg is given
if (svg && this instanceof SVG.Parent) {
-
// create temporary holder
well = document.createElementNS(SVG.ns, 'svg')
// dump raw svg
well.innerHTML = svg
// transplant nodes
- for (len = well.children.length;len--;) {
+ for (len = well.children.length; len--;) {
this.node.appendChild(well.firstElementChild)
}
@@ -243,13 +275,13 @@ SVG.Element = SVG.invent({
}
return this
- }
- // write svgjs data to the dom
- , writeDataToDom: function() {
+ },
+ // write svgjs data to the dom
+ writeDataToDom: function () {
// dump variables recursively
- if(this.is(SVG.Parent)){
- this.each(function(){
+ if (this.is(SVG.Parent)) {
+ this.each(function () {
this.writeDataToDom()
})
}
@@ -257,17 +289,18 @@ SVG.Element = SVG.invent({
// remove previously set data
this.node.removeAttribute('svgjs:data')
- if(Object.keys(this.dom).length)
+ if (Object.keys(this.dom).length) {
this.node.setAttribute('svgjs:data', JSON.stringify(this.dom)) // see #428
-
+ }
return this
- }
- // set given data to the elements data property
- , setData: function(o){
+ },
+
+ // set given data to the elements data property
+ setData: function (o) {
this.dom = o
return this
- }
- , is: function(obj){
+ },
+ is: function (obj) {
return is(this, obj)
}
}
diff --git a/src/ellipse.js b/src/ellipse.js
index da8dfea..eb310f9 100644
--- a/src/ellipse.js
+++ b/src/ellipse.js
@@ -1,53 +1,55 @@
+/* global proportionalSize */
+
SVG.Circle = SVG.invent({
// Initialize node
- create: 'circle'
+ create: 'circle',
// Inherit from
-, inherit: SVG.Shape
+ inherit: SVG.Shape,
// Add parent method
-, construct: {
+ construct: {
// Create circle element, based on ellipse
- circle: function(size) {
- return this.put(new SVG.Circle).rx(new SVG.Number(size).divide(2)).move(0, 0)
+ circle: function (size) {
+ return this.put(new SVG.Circle()).rx(new SVG.Number(size).divide(2)).move(0, 0)
}
}
})
SVG.extend([SVG.Circle, SVG.FX], {
// Radius x value
- rx: function(rx) {
+ rx: function (rx) {
return this.attr('r', rx)
- }
+ },
// Alias radius x value
-, ry: function(ry) {
+ ry: function (ry) {
return this.rx(ry)
}
})
SVG.Ellipse = SVG.invent({
// Initialize node
- create: 'ellipse'
+ create: 'ellipse',
// Inherit from
-, inherit: SVG.Shape
+ inherit: SVG.Shape,
// Add parent method
-, construct: {
+ construct: {
// Create an ellipse
- ellipse: function(width, height) {
- return this.put(new SVG.Ellipse).size(width, height).move(0, 0)
+ ellipse: function (width, height) {
+ return this.put(new SVG.Ellipse()).size(width, height).move(0, 0)
}
}
})
SVG.extend([SVG.Ellipse, SVG.Rect, SVG.FX], {
// Radius x value
- rx: function(rx) {
+ rx: function (rx) {
return this.attr('rx', rx)
- }
+ },
// Radius y value
-, ry: function(ry) {
+ ry: function (ry) {
return this.attr('ry', ry)
}
})
@@ -55,35 +57,35 @@ SVG.extend([SVG.Ellipse, SVG.Rect, SVG.FX], {
// Add common method
SVG.extend([SVG.Circle, SVG.Ellipse], {
// Move over x-axis
- x: function(x) {
- return x == null ? this.cx() - this.rx() : this.cx(x + this.rx())
- }
+ x: function (x) {
+ return x == null ? this.cx() - this.rx() : this.cx(x + this.rx())
+ },
// Move over y-axis
- , y: function(y) {
- return y == null ? this.cy() - this.ry() : this.cy(y + this.ry())
- }
+ y: function (y) {
+ return y == null ? this.cy() - this.ry() : this.cy(y + this.ry())
+ },
// Move by center over x-axis
- , cx: function(x) {
- return x == null ? this.attr('cx') : this.attr('cx', x)
- }
+ cx: function (x) {
+ return x == null ? this.attr('cx') : this.attr('cx', x)
+ },
// Move by center over y-axis
- , cy: function(y) {
- return y == null ? this.attr('cy') : this.attr('cy', y)
- }
+ cy: function (y) {
+ return y == null ? this.attr('cy') : this.attr('cy', y)
+ },
// Set width of element
- , width: function(width) {
- return width == null ? this.rx() * 2 : this.rx(new SVG.Number(width).divide(2))
- }
+ width: function (width) {
+ return width == null ? this.rx() * 2 : this.rx(new SVG.Number(width).divide(2))
+ },
// Set height of element
- , height: function(height) {
- return height == null ? this.ry() * 2 : this.ry(new SVG.Number(height).divide(2))
- }
+ height: function (height) {
+ return height == null ? this.ry() * 2 : this.ry(new SVG.Number(height).divide(2))
+ },
// Custom size function
- , size: function(width, height) {
- var p = proportionalSize(this, width, height)
+ size: function (width, height) {
+ var p = proportionalSize(this, width, height)
- return this
+ return this
.rx(new SVG.Number(p.width).divide(2))
.ry(new SVG.Number(p.height).divide(2))
- }
-}) \ No newline at end of file
+ }
+})
diff --git a/src/event.js b/src/event.js
index aec410b..c53e0b3 100644
--- a/src/event.js
+++ b/src/event.js
@@ -1,26 +1,25 @@
// Add events to elements
-;[ 'click'
- , 'dblclick'
- , 'mousedown'
- , 'mouseup'
- , 'mouseover'
- , 'mouseout'
- , 'mousemove'
+;[ 'click',
+ 'dblclick',
+ 'mousedown',
+ 'mouseup',
+ 'mouseover',
+ 'mouseout',
+ 'mousemove',
// , 'mouseenter' -> not supported by IE
// , 'mouseleave' -> not supported by IE
- , 'touchstart'
- , 'touchmove'
- , 'touchleave'
- , 'touchend'
- , 'touchcancel' ].forEach(function(event) {
-
+ 'touchstart',
+ 'touchmove',
+ 'touchleave',
+ 'touchend',
+ 'touchcancel' ].forEach(function (event) {
// add event to SVG.Element
- SVG.Element.prototype[event] = function(f) {
+ SVG.Element.prototype[event] = function (f) {
// bind event to element rather than element node
- SVG.on(this, event, f)
- return this
- }
-})
+ SVG.on(this, event, f)
+ return this
+ }
+ })
// Initialize listeners stack
SVG.listeners = []
@@ -28,22 +27,23 @@ SVG.handlerMap = []
SVG.listenerId = 0
// Add event binder in the SVG namespace
-SVG.on = function(node, events, listener, binding, options) {
- events.split(SVG.regex.delimiter).forEach(function(event) {
+SVG.on = function (node, events, listener, binding, options) {
+ events.split(SVG.regex.delimiter).forEach(function (event) {
// create listener, get object-index
- var l = listener.bind(binding || node)
- , n = node instanceof SVG.Element ? node.node : node
- , index = (SVG.handlerMap.indexOf(n) + 1 || SVG.handlerMap.push(n)) - 1
- , ev = event.split('.')[0]
- , ns = event.split('.')[1] || '*'
+ var l = listener.bind(binding || node)
+ var n = node instanceof SVG.Element ? node.node : node
+ var index = (SVG.handlerMap.indexOf(n) + 1 || SVG.handlerMap.push(n)) - 1
+ var ev = event.split('.')[0]
+ var ns = event.split('.')[1] || '*'
// ensure valid object
- SVG.listeners[index] = SVG.listeners[index] || {}
- SVG.listeners[index][ev] = SVG.listeners[index][ev] || {}
+ SVG.listeners[index] = SVG.listeners[index] || {}
+ SVG.listeners[index][ev] = SVG.listeners[index][ev] || {}
SVG.listeners[index][ev][ns] = SVG.listeners[index][ev][ns] || {}
- if(!listener._svgjsListenerId)
+ if (!listener._svgjsListenerId) {
listener._svgjsListenerId = ++SVG.listenerId
+ }
// reference listener
SVG.listeners[index][ev][ns][listener._svgjsListenerId] = l
@@ -54,17 +54,17 @@ SVG.on = function(node, events, listener, binding, options) {
}
// Add event unbinder in the SVG namespace
-SVG.off = function(node, event, listener) {
+SVG.off = function (node, event, listener) {
var index = SVG.handlerMap.indexOf(node)
- , ev = event && event.split('.')[0]
- , ns = event && event.split('.')[1]
- , namespace = ''
+ var ev = event && event.split('.')[0]
+ var ns = event && event.split('.')[1]
+ var namespace = ''
- if(index == -1) return
+ if (index === -1) return
if (listener) {
- if(typeof listener == 'function') listener = listener._svgjsListenerId
- if(!listener) return
+ if (typeof listener === 'function') listener = listener._svgjsListenerId
+ if (!listener) return
// remove listener reference
if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns || '*']) {
@@ -73,74 +73,72 @@ SVG.off = function(node, event, listener) {
delete SVG.listeners[index][ev][ns || '*'][listener]
}
-
} else if (ns && ev) {
// remove all listeners for a namespaced event
if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns]) {
- for (listener in SVG.listeners[index][ev][ns])
+ for (listener in SVG.listeners[index][ev][ns]) {
SVG.off(node, [ev, ns].join('.'), listener)
+ }
delete SVG.listeners[index][ev][ns]
}
-
- } else if (ns){
+ } else if (ns) {
// remove all listeners for a specific namespace
- for(event in SVG.listeners[index]){
- for(namespace in SVG.listeners[index][event]){
- if(ns === namespace){
- SVG.off(node, [event, ns].join('.'))
- }
+ for (event in SVG.listeners[index]) {
+ for (namespace in SVG.listeners[index][event]) {
+ if (ns === namespace) {
+ SVG.off(node, [event, ns].join('.'))
}
+ }
}
-
} else if (ev) {
// remove all listeners for the event
if (SVG.listeners[index][ev]) {
- for (namespace in SVG.listeners[index][ev])
+ for (namespace in SVG.listeners[index][ev]) {
SVG.off(node, [ev, namespace].join('.'))
+ }
delete SVG.listeners[index][ev]
}
-
} else {
// remove all listeners on a given node
- for (event in SVG.listeners[index])
+ for (event in SVG.listeners[index]) {
SVG.off(node, event)
+ }
delete SVG.listeners[index]
delete SVG.handlerMap[index]
-
}
}
//
SVG.extend(SVG.Element, {
// Bind given event to listener
- on: function(event, listener, binding, options) {
+ on: function (event, listener, binding, options) {
SVG.on(this, event, listener, binding, options)
-
return this
- }
+ },
+
// Unbind event from listener
-, off: function(event, listener) {
+ off: function (event, listener) {
SVG.off(this.node, event, listener)
-
return this
- }
- // Fire given event
-, fire: function(event, data) {
+ },
+ // Fire given event
+ fire: function (event, data) {
// Dispatch event
- if(event instanceof window.Event){
- this.node.dispatchEvent(event)
- }else{
- this.node.dispatchEvent(event = new window.CustomEvent(event, {detail:data, cancelable: true}))
+ if (event instanceof window.Event) {
+ this.node.dispatchEvent(event)
+ } else {
+ this.node.dispatchEvent(event = new window.CustomEvent(event, {detail: data, cancelable: true}))
}
this._event = event
return this
- }
-, event: function() {
+ },
+
+ event: function () {
return this._event
}
})
diff --git a/src/flatten.js b/src/flatten.js
index 356a176..1c32a76 100644
--- a/src/flatten.js
+++ b/src/flatten.js
@@ -1,15 +1,15 @@
SVG.extend(SVG.Parent, {
- flatten: function(parent) {
- if(this instanceof SVG.Defs) return this
+ flatten: function (parent) {
+ if (this instanceof SVG.Defs) return this
parent = parent || (this instanceof SVG.Doc ? this : this.parent(SVG.Parent))
- this.each(function(){
- if(this instanceof SVG.Defs) return this
- if(this instanceof SVG.Parent) return this.flatten(parent)
+ this.each(function () {
+ if (this instanceof SVG.Defs) return this
+ if (this instanceof SVG.Parent) return this.flatten(parent)
return this.toParent(parent)
})
-
+
// we need this so that SVG.Doc does not get removed
this.node.firstElementChild || this.remove()
diff --git a/src/fx.js b/src/fx.js
index ed81cc7..9fcdd4c 100644
--- a/src/fx.js
+++ b/src/fx.js
@@ -1,19 +1,19 @@
SVG.easing = {
- '-': function(pos){return pos}
-, '<>':function(pos){return -Math.cos(pos * Math.PI) / 2 + 0.5}
-, '>': function(pos){return Math.sin(pos * Math.PI / 2)}
-, '<': function(pos){return -Math.cos(pos * Math.PI / 2) + 1}
+ '-': function (pos) { return pos },
+ '<>': function (pos) { return -Math.cos(pos * Math.PI) / 2 + 0.5 },
+ '>': function (pos) { return Math.sin(pos * Math.PI / 2) },
+ '<': function (pos) { return -Math.cos(pos * Math.PI / 2) + 1 }
}
-SVG.morph = function(pos){
- return function(from, to) {
+SVG.morph = function (pos) {
+ return function (from, to) {
return new SVG.MorphObj(from, to).at(pos)
}
}
SVG.Situation = SVG.invent({
- create: function(o){
+ create: function (o) {
this.init = false
this.reversed = false
this.reversing = false
@@ -54,15 +54,13 @@ SVG.Situation = SVG.invent({
// functions to fire at a specific position
// e.g. "0.5": function foo(){}
}
-
}
})
-
SVG.FX = SVG.invent({
- create: function(element) {
+ create: function (element) {
this._target = element
this.situations = []
this.active = false
@@ -74,9 +72,9 @@ SVG.FX = SVG.invent({
// When performing a delay, absPos is below 0 and when performing a loop, its value is above 1
this.absPos = 0
this._speed = 1
- }
+ },
-, extend: {
+ extend: {
/**
* sets or returns the target of this animation
@@ -85,9 +83,8 @@ SVG.FX = SVG.invent({
* @param delay Number indicating the delay before the animation starts
* @return target || this
*/
- animate: function(o, ease, delay){
-
- if(typeof o == 'object'){
+ animate: function (o, ease, delay) {
+ if (typeof o === 'object') {
ease = o.ease
delay = o.delay
o = o.duration
@@ -102,14 +99,14 @@ SVG.FX = SVG.invent({
this.queue(situation)
return this
- }
+ },
/**
* sets a delay before the next element of the queue is called
* @param delay Duration of delay in milliseconds
* @return this.target()
*/
- , delay: function(delay){
+ delay: function (delay) {
// The delay is performed by an empty situation with its duration
// attribute set to the duration of the delay
var situation = new SVG.Situation({
@@ -119,136 +116,138 @@ SVG.FX = SVG.invent({
})
return this.queue(situation)
- }
+ },
/**
* sets or returns the target of this animation
* @param null || target SVG.Element which should be set as new target
* @return target || this
*/
- , target: function(target){
- if(target && target instanceof SVG.Element){
+ target: function (target) {
+ if (target && target instanceof SVG.Element) {
this._target = target
return this
}
return this._target
- }
+ },
// returns the absolute position at a given time
- , timeToAbsPos: function(timestamp){
- return (timestamp - this.situation.start) / (this.situation.duration/this._speed)
- }
+ timeToAbsPos: function (timestamp) {
+ return (timestamp - this.situation.start) / (this.situation.duration / this._speed)
+ },
// returns the timestamp from a given absolute positon
- , absPosToTime: function(absPos){
- return this.situation.duration/this._speed * absPos + this.situation.start
- }
+ absPosToTime: function (absPos) {
+ return this.situation.duration / this._speed * absPos + this.situation.start
+ },
// starts the animationloop
- , startAnimFrame: function(){
+ startAnimFrame: function () {
this.stopAnimFrame()
- this.animationFrame = window.requestAnimationFrame(function(){ this.step() }.bind(this))
- }
+ this.animationFrame = window.requestAnimationFrame(function () { this.step() }.bind(this))
+ },
// cancels the animationframe
- , stopAnimFrame: function(){
+ stopAnimFrame: function () {
window.cancelAnimationFrame(this.animationFrame)
- }
+ },
// kicks off the animation - only does something when the queue is currently not active and at least one situation is set
- , start: function(){
+ start: function () {
// dont start if already started
- if(!this.active && this.situation){
+ if (!this.active && this.situation) {
this.active = true
this.startCurrent()
}
return this
- }
+ },
// start the current situation
- , startCurrent: function(){
- this.situation.start = +new Date + this.situation.delay/this._speed
- this.situation.finish = this.situation.start + this.situation.duration/this._speed
+ startCurrent: function () {
+ this.situation.start = +new Date() + this.situation.delay / this._speed
+ this.situation.finish = this.situation.start + this.situation.duration / this._speed
return this.initAnimations().step()
- }
+ },
/**
* adds a function / Situation to the animation queue
* @param fn function / situation to add
* @return this
*/
- , queue: function(fn){
- if(typeof fn == 'function' || fn instanceof SVG.Situation)
+ queue: function (fn) {
+ if (typeof fn === 'function' || fn instanceof SVG.Situation) {
this.situations.push(fn)
+ }
- if(!this.situation) this.situation = this.situations.shift()
+ if (!this.situation) this.situation = this.situations.shift()
return this
- }
+ },
/**
* pulls next element from the queue and execute it
* @return this
*/
- , dequeue: function(){
+ dequeue: function () {
// stop current animation
this.stop()
// get next animation from queue
this.situation = this.situations.shift()
- if(this.situation){
- if(this.situation instanceof SVG.Situation) {
+ if (this.situation) {
+ if (this.situation instanceof SVG.Situation) {
this.start()
} else {
// If it is not a SVG.Situation, then it is a function, we execute it
- this.situation.call(this)
+ this.situation(this)
}
}
return this
- }
+ },
// updates all animations to the current state of the element
// this is important when one property could be changed from another property
- , initAnimations: function() {
+ initAnimations: function () {
var i, j, source
var s = this.situation
- if(s.init) return this
+ if (s.init) return this
- for(i in s.animations){
+ for (i in s.animations) {
source = this.target()[i]()
- if(!Array.isArray(source)) {
+ if (!Array.isArray(source)) {
source = [source]
}
- if(!Array.isArray(s.animations[i])) {
+ if (!Array.isArray(s.animations[i])) {
s.animations[i] = [s.animations[i]]
}
- //if(s.animations[i].length > source.length) {
+ // if(s.animations[i].length > source.length) {
// source.concat = source.concat(s.animations[i].slice(source.length, s.animations[i].length))
- //}
+ // }
- for(j = source.length; j--;) {
+ for (j = source.length; j--;) {
// The condition is because some methods return a normal number instead
// of a SVG.Number
- if(s.animations[i][j] instanceof SVG.Number)
+ if (s.animations[i][j] instanceof SVG.Number) {
source[j] = new SVG.Number(source[j])
+ }
s.animations[i][j] = source[j].morph(s.animations[i][j])
}
}
- for(i in s.attrs){
+ for (i in s.attrs) {
s.attrs[i] = new SVG.MorphObj(this.target().attr(i), s.attrs[i])
}
- for(i in s.styles){
+ for (i in s.styles) {
s.styles[i] = new SVG.MorphObj(this.target().css(i), s.styles[i])
}
@@ -256,29 +255,32 @@ SVG.FX = SVG.invent({
s.init = true
return this
- }
- , clearQueue: function(){
+ },
+
+ clearQueue: function () {
this.situations = []
return this
- }
- , clearCurrent: function(){
+ },
+
+ clearCurrent: function () {
this.situation = null
return this
- }
+ },
+
/** stops the animation immediately
* @param jumpToEnd A Boolean indicating whether to complete the current animation immediately.
* @param clearQueue A Boolean indicating whether to remove queued animation as well.
* @return this
*/
- , stop: function(jumpToEnd, clearQueue){
+ stop: function (jumpToEnd, clearQueue) {
var active = this.active
this.active = false
- if(clearQueue){
+ if (clearQueue) {
this.clearQueue()
}
- if(jumpToEnd && this.situation){
+ if (jumpToEnd && this.situation) {
// initialize the situation if it was not
!active && this.startCurrent()
this.atEnd()
@@ -287,58 +289,57 @@ SVG.FX = SVG.invent({
this.stopAnimFrame()
return this.clearCurrent()
- }
+ },
/** resets the element to the state where the current element has started
* @return this
*/
- , reset: function(){
- if(this.situation){
+ reset: function () {
+ if (this.situation) {
var temp = this.situation
this.stop()
this.situation = temp
this.atStart()
}
return this
- }
+ },
// Stop the currently-running animation, remove all queued animations, and complete all animations for the element.
- , finish: function(){
-
+ finish: function () {
this.stop(true, false)
- while(this.dequeue().situation && this.stop(true, false));
+ while (this.dequeue().situation && this.stop(true, false));
this.clearQueue().clearCurrent()
return this
- }
+ },
// set the internal animation pointer at the start position, before any loops, and updates the visualisation
- , atStart: function() {
+ atStart: function () {
return this.at(0, true)
- }
+ },
// set the internal animation pointer at the end position, after all the loops, and updates the visualisation
- , atEnd: function() {
+ atEnd: function () {
if (this.situation.loops === true) {
// If in a infinite loop, we end the current iteration
this.situation.loops = this.situation.loop + 1
}
- if(typeof this.situation.loops == 'number') {
+ if (typeof this.situation.loops === 'number') {
// If performing a finite number of loops, we go after all the loops
return this.at(this.situation.loops, true)
} else {
// If no loops, we just go at the end
return this.at(1, true)
}
- }
+ },
// set the internal animation pointer to the specified position and updates the visualisation
// if isAbsPos is true, pos is treated as an absolute position
- , at: function(pos, isAbsPos){
- var durDivSpd = this.situation.duration/this._speed
+ at: function (pos, isAbsPos) {
+ var durDivSpd = this.situation.duration / this._speed
this.absPos = pos
// If pos is not an absolute position, we convert it into one
@@ -347,18 +348,18 @@ SVG.FX = SVG.invent({
this.absPos += this.situation.loop
}
- this.situation.start = +new Date - this.absPos * durDivSpd
+ this.situation.start = +new Date() - this.absPos * durDivSpd
this.situation.finish = this.situation.start + durDivSpd
return this.step(true)
- }
+ },
/**
* sets or returns the speed of the animations
* @param speed null || Number The new speed of the animations
* @return Number || this
*/
- , speed: function(speed){
+ speed: function (speed) {
if (speed === 0) return this.pause()
if (speed) {
@@ -366,35 +367,35 @@ SVG.FX = SVG.invent({
// We use an absolute position here so that speed can affect the delay before the animation
return this.at(this.absPos, true)
} else return this._speed
- }
+ },
// Make loopable
- , loop: function(times, reverse) {
+ loop: function (times, reverse) {
var c = this.last()
// store total loops
c.loops = (times != null) ? times : true
c.loop = 0
- if(reverse) c.reversing = true
+ if (reverse) c.reversing = true
return this
- }
+ },
// pauses the animation
- , pause: function(){
+ pause: function () {
this.paused = true
this.stopAnimFrame()
return this
- }
+ },
// unpause the animation
- , play: function(){
- if(!this.paused) return this
+ play: function () {
+ if (!this.paused) return this
this.paused = false
// We use an absolute position here so that the delay before the animation can be paused
return this.at(this.absPos, true)
- }
+ },
/**
* toggle or set the direction of the animation
@@ -402,119 +403,117 @@ SVG.FX = SVG.invent({
* @param reversed Boolean indicating whether to reverse the animation or not (default: toggle the reverse status)
* @return this
*/
- , reverse: function(reversed){
+ reverse: function (reversed) {
var c = this.last()
- if(typeof reversed == 'undefined') c.reversed = !c.reversed
+ if (typeof reversed === 'undefined') c.reversed = !c.reversed
else c.reversed = reversed
return this
- }
-
+ },
/**
* returns a float from 0-1 indicating the progress of the current animation
* @param eased Boolean indicating whether the returned position should be eased or not
* @return number
*/
- , progress: function(easeIt){
+ progress: function (easeIt) {
return easeIt ? this.situation.ease(this.pos) : this.pos
- }
+ },
/**
* adds a callback function which is called when the current animation is finished
* @param fn Function which should be executed as callback
* @return number
*/
- , after: function(fn){
+ after: function (fn) {
var c = this.last()
- , wrapper = function wrapper(e){
- if(e.detail.situation == c){
- fn.call(this, c)
- this.off('finished.fx', wrapper) // prevent memory leak
- }
- }
+ function wrapper (e) {
+ if (e.detail.situation === c) {
+ fn.call(this, c)
+ this.off('finished.fx', wrapper) // prevent memory leak
+ }
+ }
this.target().on('finished.fx', wrapper)
return this._callStart()
- }
+ },
// adds a callback which is called whenever one animation step is performed
- , during: function(fn){
+ during: function (fn) {
var c = this.last()
- , wrapper = function(e){
- if(e.detail.situation == c){
- fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, c)
- }
- }
+ function wrapper (e) {
+ if (e.detail.situation === c) {
+ fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, c)
+ }
+ }
// see above
this.target().off('during.fx', wrapper).on('during.fx', wrapper)
- this.after(function(){
+ this.after(function () {
this.off('during.fx', wrapper)
})
return this._callStart()
- }
+ },
// calls after ALL animations in the queue are finished
- , afterAll: function(fn){
- var wrapper = function wrapper(e){
- fn.call(this)
- this.off('allfinished.fx', wrapper)
- }
+ afterAll: function (fn) {
+ var wrapper = function wrapper (e) {
+ fn.call(this)
+ this.off('allfinished.fx', wrapper)
+ }
// see above
this.target().off('allfinished.fx', wrapper).on('allfinished.fx', wrapper)
return this._callStart()
- }
+ },
// calls on every animation step for all animations
- , duringAll: function(fn){
- var wrapper = function(e){
- fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, e.detail.situation)
- }
+ duringAll: function (fn) {
+ var wrapper = function (e) {
+ fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, e.detail.situation)
+ }
this.target().off('during.fx', wrapper).on('during.fx', wrapper)
- this.afterAll(function(){
+ this.afterAll(function () {
this.off('during.fx', wrapper)
})
return this._callStart()
- }
+ },
- , last: function(){
- return this.situations.length ? this.situations[this.situations.length-1] : this.situation
- }
+ last: function () {
+ return this.situations.length ? this.situations[this.situations.length - 1] : this.situation
+ },
// adds one property to the animations
- , add: function(method, args, type){
+ add: function (method, args, type) {
this.last()[type || 'animations'][method] = args
return this._callStart()
- }
+ },
/** perform one step of the animation
* @param ignoreTime Boolean indicating whether to ignore time and use position directly or recalculate position based on time
* @return this
*/
- , step: function(ignoreTime){
-
+ step: function (ignoreTime) {
// convert current time to an absolute position
- if(!ignoreTime) this.absPos = this.timeToAbsPos(+new Date)
+ if (!ignoreTime) this.absPos = this.timeToAbsPos(+new Date())
// This part convert an absolute position to a position
- if(this.situation.loops !== false) {
+ if (this.situation.loops !== false) {
var absPos, absPosInt, lastLoop
// If the absolute position is below 0, we just treat it as if it was 0
absPos = Math.max(this.absPos, 0)
absPosInt = Math.floor(absPos)
- if(this.situation.loops === true || absPosInt < this.situation.loops) {
+ if (this.situation.loops === true || absPosInt < this.situation.loops) {
this.pos = absPos - absPosInt
lastLoop = this.situation.loop
this.situation.loop = absPosInt
@@ -526,11 +525,10 @@ SVG.FX = SVG.invent({
this.situation.loop = this.situation.loops
}
- if(this.situation.reversing) {
+ if (this.situation.reversing) {
// Toggle reversed if an odd number of loops as occured since the last call of step
- this.situation.reversed = this.situation.reversed != Boolean((this.situation.loop - lastLoop) % 2)
+ this.situation.reversed = this.situation.reversed !== Boolean((this.situation.loop - lastLoop) % 2)
}
-
} else {
// If there are no loop, the absolute position must not be above 1
this.absPos = Math.min(this.absPos, 1)
@@ -538,28 +536,27 @@ SVG.FX = SVG.invent({
}
// while the absolute position can be below 0, the position must not be below 0
- if(this.pos < 0) this.pos = 0
-
- if(this.situation.reversed) this.pos = 1 - this.pos
+ if (this.pos < 0) this.pos = 0
+ if (this.situation.reversed) this.pos = 1 - this.pos
// apply easing
var eased = this.situation.ease(this.pos)
// call once-callbacks
- for(var i in this.situation.once){
- if(i > this.lastPos && i <= eased){
+ for (var i in this.situation.once) {
+ if (i > this.lastPos && i <= eased) {
this.situation.once[i].call(this.target(), this.pos, eased)
delete this.situation.once[i]
}
}
// fire during callback with position, eased position and current situation as parameter
- if(this.active) this.target().fire('during', {pos: this.pos, eased: eased, fx: this, situation: this.situation})
+ if (this.active) this.target().fire('during', {pos: this.pos, eased: eased, fx: this, situation: this.situation})
// the user may call stop or finish in the during callback
// so make sure that we still have a valid situation
- if(!this.situation){
+ if (!this.situation) {
return this
}
@@ -567,29 +564,27 @@ SVG.FX = SVG.invent({
this.eachAt()
// do final code when situation is finished
- if((this.pos == 1 && !this.situation.reversed) || (this.situation.reversed && this.pos == 0)){
-
+ if ((this.pos === 1 && !this.situation.reversed) || (this.situation.reversed && this.pos === 0)) {
// stop animation callback
this.stopAnimFrame()
// fire finished callback with current situation as parameter
- this.target().fire('finished', {fx:this, situation: this.situation})
+ this.target().fire('finished', {fx: this, situation: this.situation})
- if(!this.situations.length){
+ if (!this.situations.length) {
this.target().fire('allfinished')
// Recheck the length since the user may call animate in the afterAll callback
- if(!this.situations.length){
+ if (!this.situations.length) {
this.target().off('.fx') // there shouldnt be any binding left, but to make sure...
this.active = false
}
}
// start next animation
- if(this.active) this.dequeue()
+ if (this.active) this.dequeue()
else this.clearCurrent()
-
- }else if(!this.paused && this.active){
+ } else if (!this.paused && this.active) {
// we continue animating when we are not at the end
this.startAnimFrame()
}
@@ -597,48 +592,44 @@ SVG.FX = SVG.invent({
// save last eased position for once callback triggering
this.lastPos = eased
return this
-
- }
+ },
// calculates the step for every property and calls block with it
- , eachAt: function(){
- var i, len, at, self = this, target = this.target(), s = this.situation
+ eachAt: function () {
+ var i, at
+ var self = this
+ var target = this.target()
+ var s = this.situation
// apply animations which can be called trough a method
- for(i in s.animations){
-
- at = [].concat(s.animations[i]).map(function(el){
+ for (i in s.animations) {
+ at = [].concat(s.animations[i]).map(function (el) {
return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
})
target[i].apply(target, at)
-
}
// apply animation which has to be applied with attr()
- for(i in s.attrs){
-
- at = [i].concat(s.attrs[i]).map(function(el){
+ for (i in s.attrs) {
+ at = [i].concat(s.attrs[i]).map(function (el) {
return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
})
target.attr.apply(target, at)
-
}
// apply animation which has to be applied with css()
- for(i in s.styles){
-
- at = [i].concat(s.styles[i]).map(function(el){
+ for (i in s.styles) {
+ at = [i].concat(s.styles[i]).map(function (el) {
return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
})
target.css.apply(target, at)
-
}
// animate initialTransformation which has to be chained
- if(s.transforms.length){
+ if (s.transforms.length) {
// TODO: ANIMATE THE TRANSFORMS
@@ -674,71 +665,69 @@ SVG.FX = SVG.invent({
}
return this
-
- }
-
+ },
// adds an once-callback which is called at a specific position and never again
- , once: function(pos, fn, isEased){
+ once: function (pos, fn, isEased) {
var c = this.last()
- if(!isEased) pos = c.ease(pos)
+ if (!isEased) pos = c.ease(pos)
c.once[pos] = fn
return this
- }
+ },
- , _callStart: function() {
- setTimeout(function(){this.start()}.bind(this), 0)
+ _callStart: function () {
+ setTimeout(function () { this.start() }.bind(this), 0)
return this
}
- }
+ },
-, parent: SVG.Element
+ parent: SVG.Element,
// Add method to parent elements
-, construct: {
+ construct: {
// Get fx module or create a new one, then animate with given duration and ease
- animate: function(o, ease, delay) {
+ animate: function (o, ease, delay) {
return (this.fx || (this.fx = new SVG.FX(this))).animate(o, ease, delay)
- }
- , delay: function(delay){
+ },
+ delay: function (delay) {
return (this.fx || (this.fx = new SVG.FX(this))).delay(delay)
- }
- , stop: function(jumpToEnd, clearQueue) {
- if (this.fx)
+ },
+ stop: function (jumpToEnd, clearQueue) {
+ if (this.fx) {
this.fx.stop(jumpToEnd, clearQueue)
+ }
return this
- }
- , finish: function() {
- if (this.fx)
+ },
+ finish: function () {
+ if (this.fx) {
this.fx.finish()
+ }
return this
- }
+ },
// Pause current animation
- , pause: function() {
- if (this.fx)
+ pause: function () {
+ if (this.fx) {
this.fx.pause()
+ }
return this
- }
+ },
// Play paused current animation
- , play: function() {
- if (this.fx)
- this.fx.play()
+ play: function () {
+ if (this.fx) { this.fx.play() }
return this
- }
+ },
// Set/Get the speed of the animations
- , speed: function(speed) {
- if (this.fx)
- if (speed == null)
- return this.fx.speed()
- else
- this.fx.speed(speed)
+ speed: function (speed) {
+ if (this.fx) {
+ if (speed == null) { return this.fx.speed() } else { this.fx.speed(speed) }
+ }
return this
}
@@ -749,25 +738,25 @@ SVG.FX = SVG.invent({
// MorphObj is used whenever no morphable object is given
SVG.MorphObj = SVG.invent({
- create: function(from, to){
+ create: function (from, to) {
// prepare color for morphing
- if(SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
+ if (SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
// prepare value list for morphing
- if(SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
+ if (SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
// prepare number for morphing
- if(SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
+ if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
// prepare for plain morphing
this.value = from
this.destination = to
- }
+ },
-, extend: {
- at: function(pos, real){
+ extend: {
+ at: function (pos, real) {
return real < 1 ? this.value : this.destination
},
- valueOf: function(){
+ valueOf: function () {
return this.value
}
}
@@ -776,140 +765,139 @@ SVG.MorphObj = SVG.invent({
SVG.extend(SVG.FX, {
// Add animatable attributes
- attr: function(a, v, relative) {
+ attr: function (a, v, relative) {
// apply attributes individually
- if (typeof a == 'object') {
- for (var key in a)
+ if (typeof a === 'object') {
+ for (var key in a) {
this.attr(key, a[key])
-
+ }
} else {
this.add(a, v, 'attrs')
}
return this
- }
+ },
// Add animatable styles
-, css: function(s, v) {
- if (typeof s == 'object')
- for (var key in s)
+ css: function (s, v) {
+ if (typeof s === 'object') {
+ for (var key in s) {
this.css(key, s[key])
-
- else
+ }
+ } else {
this.add(s, v, 'styles')
+ }
return this
- }
+ },
// Animatable x-axis
-, x: function(x, relative) {
- if(this.target() instanceof SVG.G){
- this.transform({x:x}, relative)
+ x: function (x, relative) {
+ if (this.target() instanceof SVG.G) {
+ this.transform({x: x}, relative)
return this
}
var num = new SVG.Number(x)
num.relative = relative
return this.add('x', num)
- }
+ },
// Animatable y-axis
-, y: function(y, relative) {
- if(this.target() instanceof SVG.G){
- this.transform({y:y}, relative)
+ y: function (y, relative) {
+ if (this.target() instanceof SVG.G) {
+ this.transform({y: y}, relative)
return this
}
var num = new SVG.Number(y)
num.relative = relative
return this.add('y', num)
- }
+ },
// Animatable center x-axis
-, cx: function(x) {
+ cx: function (x) {
return this.add('cx', new SVG.Number(x))
- }
+ },
// Animatable center y-axis
-, cy: function(y) {
+ cy: function (y) {
return this.add('cy', new SVG.Number(y))
- }
+ },
// Add animatable move
-, move: function(x, y) {
+ move: function (x, y) {
return this.x(x).y(y)
- }
+ },
// Add animatable center
-, center: function(x, y) {
+ center: function (x, y) {
return this.cx(x).cy(y)
- }
+ },
// Add animatable size
-, size: function(width, height) {
+ size: function (width, height) {
if (this.target() instanceof SVG.Text) {
// animate font size for Text elements
this.attr('font-size', width)
-
} else {
// animate bbox based size for all other elements
var box
- if(!width || !height){
+ if (!width || !height) {
box = this.target().bbox()
}
- if(!width){
- width = box.width / box.height * height
+ if (!width) {
+ width = box.width / box.height * height
}
- if(!height){
- height = box.height / box.width * width
+ if (!height) {
+ height = box.height / box.width * width
}
- this.add('width' , new SVG.Number(width))
+ this.add('width', new SVG.Number(width))
.add('height', new SVG.Number(height))
-
}
return this
- }
+ },
// Add animatable width
-, width: function(width) {
+ width: function (width) {
return this.add('width', new SVG.Number(width))
- }
+ },
// Add animatable height
-, height: function(height) {
+ height: function (height) {
return this.add('height', new SVG.Number(height))
- }
+ },
// Add animatable plot
-, plot: function(a, b, c, d) {
+ plot: function (a, b, c, d) {
// Lines can be plotted with 4 arguments
- if(arguments.length == 4) {
+ if (arguments.length === 4) {
return this.plot([a, b, c, d])
}
- return this.add('plot', new (this.target().morphArray)(a))
- }
+ return this.add('plot', new (this.target().MorphArray)(a))
+ },
// Add leading method
-, leading: function(value) {
- return this.target().leading ?
- this.add('leading', new SVG.Number(value)) :
- this
- }
+ leading: function (value) {
+ return this.target().leading
+ ? this.add('leading', new SVG.Number(value))
+ : this
+ },
// Add animatable viewbox
-, viewbox: function(x, y, width, height) {
+ viewbox: function (x, y, width, height) {
if (this.target() instanceof SVG.Container) {
this.add('viewbox', new SVG.Box(x, y, width, height))
}
return this
- }
-, update: function(o) {
+ },
+ update: function (o) {
if (this.target() instanceof SVG.Stop) {
- if (typeof o == 'number' || o instanceof SVG.Number) {
+ if (typeof o === 'number' || o instanceof SVG.Number) {
return this.update({
- offset: arguments[0]
- , color: arguments[1]
- , opacity: arguments[2]
+ offset: arguments[0],
+ color: arguments[1],
+ opacity: arguments[2]
})
}
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', o.offset)
+ if (o.color != null) this.attr('stop-color', o.color)
+ if (o.offset != null) this.attr('offset', o.offset)
}
return this
diff --git a/src/gradient.js b/src/gradient.js
index 4c8ed30..ea2197b 100644
--- a/src/gradient.js
+++ b/src/gradient.js
@@ -1,48 +1,49 @@
SVG.Gradient = SVG.invent({
// Initialize node
- create: function(type) {
- this.constructor.call(this, typeof type == 'object' ? type : SVG.create(type + 'Gradient'))
- }
+ create: function (type) {
+ this.constructor(typeof type === 'object' ? type : SVG.create(type + 'Gradient'))
+ },
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
// Add class methods
-, extend: {
+ extend: {
// Add a color stop
- stop: function(offset, color, opacity) {
- return this.put(new SVG.Stop).update(offset, color, opacity)
- }
+ stop: function (offset, color, opacity) {
+ return this.put(new SVG.Stop()).update(offset, color, opacity)
+ },
// Update gradient
- , update: function(block) {
- // remove all stops
+ update: function (block) {
+ // remove all stops
this.clear()
-
- // invoke passed block
- if (typeof block == 'function')
+
+ // invoke passed block
+ if (typeof block === 'function') {
block.call(this, this)
-
+ }
+
return this
- }
+ },
// Return the fill id
- , url: function() {
+ url: function () {
return 'url(#' + this.id() + ')'
- }
+ },
// Alias string convertion to fill
- , toString: function() {
+ toString: function () {
return this.url()
- }
+ },
// custom attr to handle transform
- , attr: function(a, b, c) {
- if(a == 'transform') a = 'gradientTransform'
+ attr: function (a, b, c) {
+ if (a === 'transform') a = 'gradientTransform'
return SVG.Container.prototype.attr.call(this, a, b, c)
}
- }
-
+ },
+
// Add parent method
-, construct: {
+ construct: {
// Create gradient element in defs
- gradient: function(type, block) {
+ gradient: function (type, block) {
return this.defs().gradient(type, block)
}
}
@@ -51,51 +52,51 @@ SVG.Gradient = SVG.invent({
// Add animatable methods to both gradient and fx module
SVG.extend([SVG.Gradient, SVG.FX], {
// From position
- from: function(x, y) {
- return (this._target || this).type == 'radialGradient' ?
- this.attr({ fx: new SVG.Number(x), fy: new SVG.Number(y) }) :
- this.attr({ x1: new SVG.Number(x), y1: new SVG.Number(y) })
- }
+ from: function (x, y) {
+ return (this._target || this).type === 'radialGradient'
+ ? 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._target || this).type == 'radialGradient' ?
- this.attr({ cx: new SVG.Number(x), cy: new SVG.Number(y) }) :
- this.attr({ x2: new SVG.Number(x), y2: new SVG.Number(y) })
+ to: function (x, y) {
+ return (this._target || this).type === 'radialGradient'
+ ? this.attr({ cx: new SVG.Number(x), cy: new SVG.Number(y) })
+ : this.attr({ x2: new SVG.Number(x), y2: new SVG.Number(y) })
}
})
// Base gradient generation
SVG.extend(SVG.Defs, {
// define gradient
- gradient: function(type, block) {
+ gradient: function (type, block) {
return this.put(new SVG.Gradient(type)).update(block)
}
-
+
})
SVG.Stop = SVG.invent({
// Initialize node
- create: 'stop'
+ create: 'stop',
// Inherit from
-, inherit: SVG.Element
+ inherit: SVG.Element,
// Add class methods
-, extend: {
+ extend: {
// add color stops
- update: function(o) {
- if (typeof o == 'number' || o instanceof SVG.Number) {
+ update: function (o) {
+ if (typeof o === 'number' || o instanceof SVG.Number) {
o = {
- offset: arguments[0]
- , color: arguments[1]
- , opacity: arguments[2]
+ offset: arguments[0],
+ color: arguments[1],
+ opacity: arguments[2]
}
}
- // set attributes
+ // 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))
+ if (o.color != null) this.attr('stop-color', o.color)
+ if (o.offset != null) this.attr('offset', new SVG.Number(o.offset))
return this
}
diff --git a/src/group.js b/src/group.js
index 9ec89f2..f0d3d8b 100644
--- a/src/group.js
+++ b/src/group.js
@@ -1,50 +1,49 @@
SVG.G = SVG.invent({
// Initialize node
- create: 'g'
+ create: 'g',
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
// Add class methods
-, extend: {
+ extend: {
// Move over x-axis
- x: function(x) {
+ x: function (x) {
return x == null ? this.transform('x') : this.transform({ x: x - this.x() }, true)
- }
+ },
// Move over y-axis
- , y: function(y) {
+ y: function (y) {
return y == null ? this.transform('y') : this.transform({ y: y - this.y() }, true)
- }
+ },
// Move by center over x-axis
- , cx: function(x) {
+ cx: function (x) {
return x == null ? this.gbox().cx : this.x(x - this.gbox().width / 2)
- }
+ },
// Move by center over y-axis
- , cy: function(y) {
+ cy: function (y) {
return y == null ? this.gbox().cy : this.y(y - this.gbox().height / 2)
- }
- , gbox: function() {
-
- var bbox = this.bbox()
- , trans = this.transform()
+ },
+ gbox: function () {
+ var bbox = this.bbox()
+ var trans = this.transform()
- bbox.x += trans.x
+ bbox.x += trans.x
bbox.x2 += trans.x
bbox.cx += trans.x
- bbox.y += trans.y
+ bbox.y += trans.y
bbox.y2 += trans.y
bbox.cy += trans.y
return bbox
}
- }
+ },
// Add parent method
-, construct: {
+ construct: {
// Create a group element
- group: function() {
- return this.put(new SVG.G)
+ group: function () {
+ return this.put(new SVG.G())
}
}
})
diff --git a/src/helpers.js b/src/helpers.js
index b6c2fe6..56565a0 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -1,15 +1,17 @@
-function createElement(element, makeNested) {
- if(element instanceof SVG.Element) return element
+/* eslint no-unused-vars: 0 */
- if(typeof element == 'object') {
+function createElement (element, makeNested) {
+ if (element instanceof SVG.Element) return element
+
+ if (typeof element === 'object') {
return SVG.adopt(element)
}
- if(element == null) {
+ if (element == null) {
return new SVG.Doc()
}
- if(typeof element == 'string' && element.charAt(0) != '<') {
+ if (typeof element === 'string' && element.charAt(0) !== '<') {
return SVG.adopt(document.querySelector(element))
}
@@ -21,111 +23,114 @@ function createElement(element, makeNested) {
return element
}
-function isNulledBox(box) {
+function isNulledBox (box) {
return !box.w && !box.h && !box.x && !box.y
}
-function domContains(node) {
- return (document.documentElement.contains || function(node) {
+function domContains (node) {
+ return (document.documentElement.contains || function (node) {
// This is IE - it does not support contains() for top-level SVGs
- while (node.parentNode){
- node = node.parentNode;
+ while (node.parentNode) {
+ node = node.parentNode
}
- return node == document
+ return node === document
}).call(document.documentElement, node)
}
-function pathRegReplace(a, b, c, d) {
+function pathRegReplace (a, b, c, d) {
return c + d.replace(SVG.regex.dots, ' .')
}
// creates deep clone of array
-function array_clone(arr){
+function arrayClone (arr) {
var clone = arr.slice(0)
- for(var i = clone.length; i--;){
- if(Array.isArray(clone[i])){
- clone[i] = array_clone(clone[i])
+ for (var i = clone.length; i--;) {
+ if (Array.isArray(clone[i])) {
+ clone[i] = arrayClone(clone[i])
}
}
return clone
}
// tests if a given element is instance of an object
-function is(el, obj){
+function is (el, obj) {
return el instanceof obj
}
// tests if a given selector matches an element
-function matches(el, selector) {
- return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);
+function matches (el, selector) {
+ return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector)
}
// Convert dash-separated-string to camelCase
-function camelCase(s) {
- return s.toLowerCase().replace(/-(.)/g, function(m, g) {
+function camelCase (s) {
+ return s.toLowerCase().replace(/-(.)/g, function (m, g) {
return g.toUpperCase()
})
}
// Capitalize first letter of a string
-function capitalize(s) {
+function capitalize (s) {
return s.charAt(0).toUpperCase() + s.slice(1)
}
// Ensure to six-based hex
-function fullHex(hex) {
- return hex.length == 4 ?
- [ '#',
- hex.substring(1, 2), hex.substring(1, 2)
- , hex.substring(2, 3), hex.substring(2, 3)
- , hex.substring(3, 4), hex.substring(3, 4)
- ].join('') : hex
+function fullHex (hex) {
+ return hex.length === 4
+ ? [ '#',
+ hex.substring(1, 2), hex.substring(1, 2),
+ hex.substring(2, 3), hex.substring(2, 3),
+ hex.substring(3, 4), hex.substring(3, 4)
+ ].join('')
+ : hex
}
// Component to hex value
-function compToHex(comp) {
+function compToHex (comp) {
var hex = comp.toString(16)
- return hex.length == 1 ? '0' + hex : hex
+ return hex.length === 1 ? '0' + hex : hex
}
// Calculate proportional width and height values when necessary
-function proportionalSize(element, width, height) {
+function proportionalSize (element, width, height) {
if (width == null || height == null) {
var box = element.bbox()
- if (width == null)
+ if (width == null) {
width = box.width / box.height * height
- else if (height == null)
+ } else if (height == null) {
height = box.height / box.width * width
+ }
}
return {
- width: width
- , height: height
+ width: width,
+ height: height
}
}
// Map matrix array to object
-function arrayToMatrix(a) {
+function arrayToMatrix (a) {
return { a: a[0], b: a[1], c: a[2], d: a[3], e: a[4], f: a[5] }
}
// Parse matrix if required
-function parseMatrix(matrix) {
- if (!(matrix instanceof SVG.Matrix))
+function parseMatrix (matrix) {
+ if (!(matrix instanceof SVG.Matrix)) {
matrix = new SVG.Matrix(matrix)
+ }
return matrix
}
// Add centre point to transform object
-function ensureCentre(o, target) {
+function ensureCentre (o, target) {
o.cx = o.cx == null ? target.bbox().cx : o.cx
o.cy = o.cy == null ? target.bbox().cy : o.cy
}
// PathArray Helpers
-function arrayToString(a) {
+function arrayToString (a) {
for (var i = 0, il = a.length, s = ''; i < il; i++) {
s += a[i][0]
@@ -162,28 +167,30 @@ function arrayToString(a) {
}
// Deep new id assignment
-function assignNewId(node) {
+function assignNewId (node) {
// do the same for SVG child nodes as well
- for (var i = node.children.length - 1; i >= 0; i--)
+ for (var i = node.children.length - 1; i >= 0; i--) {
assignNewId(node.children[i])
+ }
- if(node.id)
+ if (node.id) {
return SVG.adopt(node).id(SVG.eid(node.nodeName))
+ }
return SVG.adopt(node)
}
// Add more bounding box properties
-function fullBox(b) {
+function fullBox (b) {
if (b.x == null) {
- b.x = 0
- b.y = 0
- b.width = 0
+ b.x = 0
+ b.y = 0
+ b.width = 0
b.height = 0
}
- b.w = b.width
- b.h = b.height
+ b.w = b.width
+ b.h = b.height
b.x2 = b.x + b.width
b.y2 = b.y + b.height
b.cx = b.x + b.width / 2
@@ -193,7 +200,7 @@ function fullBox(b) {
}
// Get id from reference string
-function idFromReference(url) {
+function idFromReference (url) {
var m = (url || '').toString().match(SVG.regex.reference)
if (m) return m[1]
@@ -211,8 +218,8 @@ function mag (a, b) {
// of this point projected onto the unit circle directly
function unitCircle (a, b) {
var len = Math.sqrt(a * a + b * b)
- , cos = a / len
- , sin = b / len
- , theta = Math.atan2(b, a) * 180 / Math.PI
+ var cos = a / len
+ var sin = b / len
+ var theta = Math.atan2(b, a) * 180 / Math.PI
return {theta: theta, cos: cos, sin: sin}
}
diff --git a/src/hyperlink.js b/src/hyperlink.js
index 1259721..cb0a341 100644
--- a/src/hyperlink.js
+++ b/src/hyperlink.js
@@ -1,42 +1,41 @@
SVG.A = SVG.invent({
// Initialize node
- create: 'a'
+ create: 'a',
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
// Add class methods
-, extend: {
+ extend: {
// Link url
- to: function(url) {
+ to: function (url) {
return this.attr('href', url, SVG.xlink)
- }
+ },
// Link target attribute
- , target: function(target) {
+ target: function (target) {
return this.attr('target', target)
}
- }
-
+ },
+
// Add parent method
-, construct: {
+ construct: {
// Create a hyperlink element
- link: function(url) {
- return this.put(new SVG.A).to(url)
+ link: function (url) {
+ return this.put(new SVG.A()).to(url)
}
}
})
SVG.extend(SVG.Element, {
// Create a hyperlink element
- linkTo: function(url) {
- var link = new SVG.A
+ linkTo: function (url) {
+ var link = new SVG.A()
- if (typeof url == 'function')
- url.call(link, link)
- else
+ if (typeof url === 'function') { url.call(link, link) } else {
link.to(url)
+ }
return this.parent().put(link).put(this)
}
-
-}) \ No newline at end of file
+
+})
diff --git a/src/image.js b/src/image.js
index 6f8ba5b..f9395eb 100644
--- a/src/image.js
+++ b/src/image.js
@@ -1,55 +1,57 @@
SVG.Image = SVG.invent({
// Initialize node
- create: 'image'
+ create: 'image',
// Inherit from
-, inherit: SVG.Shape
+ inherit: SVG.Shape,
// Add class methods
-, extend: {
+ extend: {
// (re)load image
- load: function(url, callback) {
+ load: function (url, callback) {
if (!url) return this
var img = new window.Image()
- SVG.on(img, 'load', function(e) {
+ SVG.on(img, 'load', function (e) {
var p = this.parent(SVG.Pattern)
// ensure image size
- if (this.width() == 0 && this.height() == 0)
+ if (this.width() === 0 && this.height() === 0) {
this.size(img.width, img.height)
+ }
- if(p instanceof SVG.Pattern) {
+ if (p instanceof SVG.Pattern) {
// ensure pattern size if not set
- if (p.width() == 0 && p.height() == 0)
+ if (p.width() === 0 && p.height() === 0) {
p.size(this.width(), this.height())
+ }
}
- if(typeof callback == 'function') {
+ if (typeof callback === 'function') {
callback.call(this, {
- width: img.width
- , height: img.height
- , ratio: img.width / img.height
- , url: url
+ width: img.width,
+ height: img.height,
+ ratio: img.width / img.height,
+ url: url
})
}
}, this)
- SVG.on(img, 'load error', function() {
+ SVG.on(img, 'load error', function () {
// dont forget to unbind memory leaking events
SVG.off(img)
})
return this.attr('href', (img.src = url), SVG.xlink)
}
- }
+ },
// Add parent method
-, construct: {
+ construct: {
// create image element, load image and set its size
- image: function(source, callback) {
- return this.put(new SVG.Image).size(0, 0).load(source, callback)
+ image: function (source, callback) {
+ return this.put(new SVG.Image()).size(0, 0).load(source, callback)
}
}
})
diff --git a/src/line.js b/src/line.js
index 9e8692f..100d625 100644
--- a/src/line.js
+++ b/src/line.js
@@ -1,50 +1,52 @@
+/* global proportionalSize */
+
SVG.Line = SVG.invent({
// Initialize node
- create: 'line'
+ create: 'line',
// Inherit from
-, inherit: SVG.Shape
+ inherit: SVG.Shape,
// Add class methods
-, extend: {
+ extend: {
// Get array
- array: function() {
+ array: function () {
return new SVG.PointArray([
- [ this.attr('x1'), this.attr('y1') ]
- , [ this.attr('x2'), this.attr('y2') ]
+ [ this.attr('x1'), this.attr('y1') ],
+ [ this.attr('x2'), this.attr('y2') ]
])
- }
+ },
// Overwrite native plot() method
- , plot: function(x1, y1, x2, y2) {
- if (x1 == null)
+ plot: function (x1, y1, x2, y2) {
+ if (x1 == null) {
return this.array()
- else if (typeof y1 !== 'undefined')
+ } else if (typeof y1 !== 'undefined') {
x1 = { x1: x1, y1: y1, x2: x2, y2: y2 }
- else
+ } else {
x1 = new SVG.PointArray(x1).toLine()
+ }
return this.attr(x1)
- }
+ },
// Move by left top corner
- , move: function(x, y) {
+ move: function (x, y) {
return this.attr(this.array().move(x, y).toLine())
- }
+ },
// Set element size to given width and height
- , size: function(width, height) {
+ size: function (width, height) {
var p = proportionalSize(this, width, height)
-
return this.attr(this.array().size(p.width, p.height).toLine())
}
- }
+ },
// Add parent method
-, construct: {
+ construct: {
// Create a line element
- line: function(x1, y1, x2, y2) {
+ line: function (x1, y1, x2, y2) {
// make sure plot is called as a setter
// x1 is not necessarily a number, it can also be an array, a string and a SVG.PointArray
return SVG.Line.prototype.plot.apply(
- this.put(new SVG.Line)
+ this.put(new SVG.Line())
, x1 != null ? [x1, y1, x2, y2] : [0, 0, 0, 0]
)
}
diff --git a/src/marker.js b/src/marker.js
index fc4bf4e..32f8e4e 100644
--- a/src/marker.js
+++ b/src/marker.js
@@ -1,44 +1,43 @@
SVG.Marker = SVG.invent({
// Initialize node
- create: 'marker'
+ create: 'marker',
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
// Add class methods
-, extend: {
+ extend: {
// Set width of element
- width: function(width) {
+ width: function (width) {
return this.attr('markerWidth', width)
- }
+ },
// Set height of element
- , height: function(height) {
+ height: function (height) {
return this.attr('markerHeight', height)
- }
+ },
// Set marker refX and refY
- , ref: function(x, y) {
+ ref: function (x, y) {
return this.attr('refX', x).attr('refY', y)
- }
+ },
// Update marker
- , update: function(block) {
- // remove all content
+ update: function (block) {
+ // remove all content
this.clear()
-
- // invoke passed block
- if (typeof block == 'function')
- block.call(this, this)
-
+
+ // invoke passed block
+ if (typeof block === 'function') { block.call(this, this) }
+
return this
- }
+ },
// Return the fill id
- , toString: function() {
+ toString: function () {
return 'url(#' + this.id() + ')'
}
- }
+ },
// Add parent method
-, construct: {
- marker: function(width, height, block) {
+ construct: {
+ marker: function (width, height, block) {
// Create marker element in defs
return this.defs().marker(width, height, block)
}
@@ -48,33 +47,32 @@ SVG.Marker = SVG.invent({
SVG.extend(SVG.Defs, {
// Create marker
- marker: function(width, height, block) {
+ marker: function (width, height, block) {
// Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto
- return this.put(new SVG.Marker)
+ return this.put(new SVG.Marker())
.size(width, height)
.ref(width / 2, height / 2)
.viewbox(0, 0, width, height)
.attr('orient', 'auto')
.update(block)
}
-
+
})
SVG.extend([SVG.Line, SVG.Polyline, SVG.Polygon, SVG.Path], {
// Create and attach markers
- marker: function(marker, width, height, block) {
+ marker: function (marker, width, height, block) {
var attr = ['marker']
// Build attribute name
- if (marker != 'all') attr.push(marker)
+ if (marker !== 'all') attr.push(marker)
attr = attr.join('-')
// Set marker attribute
- marker = arguments[1] instanceof SVG.Marker ?
- arguments[1] :
- this.doc().marker(width, height, block)
-
+ marker = arguments[1] instanceof SVG.Marker
+ ? arguments[1]
+ : this.doc().marker(width, height, block)
+
return this.attr(attr, marker)
}
-
-}) \ No newline at end of file
+})
diff --git a/src/mask.js b/src/mask.js
index 610608e..e40d80f 100644
--- a/src/mask.js
+++ b/src/mask.js
@@ -1,52 +1,51 @@
SVG.Mask = SVG.invent({
// Initialize node
- create: 'mask'
+ create: 'mask',
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
// Add class methods
-, extend: {
+ extend: {
// Unmask all masked elements and remove itself
- remove: function() {
+ remove: function () {
// unmask all targets
- this.targets().forEach(function(el) {
+ this.targets().forEach(function (el) {
el.unmask()
})
// remove mask from parent
return SVG.Element.prototype.remove.call(this)
- }
+ },
- , targets: function() {
+ targets: function () {
return SVG.select('svg [mask*="' + this.id() + '"]')
}
- }
+ },
// Add parent method
-, construct: {
+ construct: {
// Create masking element
- mask: function() {
- return this.defs().put(new SVG.Mask)
+ mask: function () {
+ return this.defs().put(new SVG.Mask())
}
}
})
-
SVG.extend(SVG.Element, {
// Distribute mask to svg element
- maskWith: function(element) {
+ maskWith: function (element) {
// use given mask or create a new one
var masker = element instanceof SVG.Mask ? element : this.parent().mask().add(element)
// apply mask
return this.attr('mask', 'url("#' + masker.id() + '")')
- }
+ },
// Unmask element
-, unmask: function() {
+ unmask: function () {
return this.attr('mask', null)
- }
-, masker: function() {
+ },
+ masker: function () {
return this.reference('mask')
}
})
diff --git a/src/matrix.js b/src/matrix.js
index cde44ca..48ed7a1 100644
--- a/src/matrix.js
+++ b/src/matrix.js
@@ -1,25 +1,26 @@
+/* global abcdef, arrayToMatrix, deltaTransformPoint, parseMatrix */
+
SVG.Matrix = SVG.invent({
// Initialize
- create: function(source) {
- var i, base = arrayToMatrix([1, 0, 0, 1, 0, 0])
+ create: function (source) {
+ var base = arrayToMatrix([1, 0, 0, 1, 0, 0])
+ var i
// ensure source as object
- source = source instanceof SVG.Element ?
- source.matrixify() :
- typeof source === 'string' ?
- arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat)) :
- arguments.length == 6 ?
- arrayToMatrix([].slice.call(arguments)) :
- Array.isArray(source) ?
- arrayToMatrix(source) :
- typeof source === 'object' ?
- source : base
+ source = source instanceof SVG.Element ? source.matrixify()
+ : typeof source === 'string' ? arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat))
+ : arguments.length === 6 ? arrayToMatrix([].slice.call(arguments))
+ : Array.isArray(source) ? arrayToMatrix(source)
+ : typeof source === 'object' ? source
+ : base
// merge source
- for (i = abcdef.length - 1; i >= 0; --i)
- this[abcdef[i]] = source[abcdef[i]] != null ?
- source[abcdef[i]] : base[abcdef[i]]
- }
+ for (i = abcdef.length - 1; i >= 0; --i) {
+ this[abcdef[i]] = source[abcdef[i]] != null
+ ? source[abcdef[i]]
+ : base[abcdef[i]]
+ }
+ },
// Add methods
, extend: {
@@ -104,8 +105,29 @@ SVG.Matrix = SVG.invent({
// Store the matrix
, matrix: new SVG.Matrix(this)
+ // translation
+ x: this.e,
+ y: this.f,
+ transformedX: (this.e * Math.cos(skewX * Math.PI / 180) + this.f * Math.sin(skewX * Math.PI / 180)) / Math.sqrt(this.a * this.a + this.b * this.b),
+ transformedY: (this.f * Math.cos(skewX * Math.PI / 180) + this.e * Math.sin(-skewX * Math.PI / 180)) / Math.sqrt(this.c * this.c + this.d * this.d),
+ // skew
+ skewX: -skewX,
+ skewY: 180 / Math.PI * Math.atan2(py.y, py.x),
+ // scale
+ scaleX: Math.sqrt(this.a * this.a + this.b * this.b),
+ scaleY: Math.sqrt(this.c * this.c + this.d * this.d),
+ // rotation
+ rotation: skewX,
+ a: this.a,
+ b: this.b,
+ c: this.c,
+ d: this.d,
+ e: this.e,
+ f: this.f,
+ matrix: new SVG.Matrix(this)
+>>>>>>> 3.0.0
}
- }
+ },
// Clone matrix
, form: function (o) {
@@ -152,40 +174,42 @@ SVG.Matrix = SVG.invent({
return result
}
, clone: function() {
+ clone: function () {
+>>>>>>> 3.0.0
return new SVG.Matrix(this)
- }
+ },
// Morph one matrix into another
- , morph: function(matrix) {
+ morph: function (matrix) {
// store new destination
this.destination = new SVG.Matrix(matrix)
return this
- }
+ },
// Get morphed matrix at a given position
- , at: function(pos) {
+ at: function (pos) {
// make sure a destination is defined
if (!this.destination) return this
// calculate morphed matrix at a given position
var matrix = new SVG.Matrix({
- a: this.a + (this.destination.a - this.a) * pos
- , b: this.b + (this.destination.b - this.b) * pos
- , c: this.c + (this.destination.c - this.c) * pos
- , d: this.d + (this.destination.d - this.d) * pos
- , e: this.e + (this.destination.e - this.e) * pos
- , f: this.f + (this.destination.f - this.f) * pos
+ a: this.a + (this.destination.a - this.a) * pos,
+ b: this.b + (this.destination.b - this.b) * pos,
+ c: this.c + (this.destination.c - this.c) * pos,
+ d: this.d + (this.destination.d - this.d) * pos,
+ e: this.e + (this.destination.e - this.e) * pos,
+ f: this.f + (this.destination.f - this.f) * pos
})
return matrix
- }
+ },
// Multiplies by given matrix
- , multiply: function(matrix) {
+ multiply: function (matrix) {
return new SVG.Matrix(this.native().multiply(parseMatrix(matrix).native()))
- }
+ },
// Inverses matrix
- , inverse: function() {
+ inverse: function () {
return new SVG.Matrix(this.native().inverse())
- }
+ },
// Translate matrix
, translate: function(x, y) {
var translation = new SVG.Matrix(this.native().translate(x || 0, y || 0))
@@ -197,7 +221,7 @@ SVG.Matrix = SVG.invent({
// Support uniform scaling
if (arguments.length == 1) {
y = x
- } else if (arguments.length == 3) {
+ } else if (arguments.length === 3) {
cy = cx
cx = y
y = x
@@ -222,13 +246,11 @@ SVG.Matrix = SVG.invent({
return matrix
}
// Flip matrix on x or y, at a given offset
- , flip: function(a, o) {
- return a == 'x' ?
- this.scale(-1, 1, o, 0) :
- a == 'y' ?
- this.scale(1, -1, 0, o) :
- this.scale(-1, -1, a, o != null ? o : a)
- }
+ flip: function (a, o) {
+ return a === 'x' ? this.scale(-1, 1, o, 0)
+ : a === 'y' ? this.scale(1, -1, 0, o)
+ : this.scale(-1, -1, a, o != null ? o : a)
+ },
// Skew
, shear: function(a, cx, cy) {
var shear = new SVG.Matrix(1, a, 0, 1, 0, 0)
@@ -238,9 +260,9 @@ SVG.Matrix = SVG.invent({
}
, skew: function(x, y, cx, cy) {
// support uniformal skew
- if (arguments.length == 1) {
+ if (arguments.length === 1) {
y = x
- } else if (arguments.length == 3) {
+ } else if (arguments.length === 3) {
cy = cx
cx = y
y = x
@@ -257,61 +279,60 @@ SVG.Matrix = SVG.invent({
return matrix
}
// SkewX
- , skewX: function(x, cx, cy) {
+ skewX: function (x, cx, cy) {
return this.skew(x, 0, cx, cy)
- }
+ },
// SkewY
- , skewY: function(y, cx, cy) {
+ skewY: function (y, cx, cy) {
return this.skew(0, y, cx, cy)
- }
+ },
// Transform around a center point
- , around: function(cx, cy, matrix) {
+ around: function (cx, cy, matrix) {
return this
.multiply(new SVG.Matrix(1, 0, 0, 1, cx || 0, cy || 0))
.multiply(matrix)
.multiply(new SVG.Matrix(1, 0, 0, 1, -cx || 0, -cy || 0))
- }
+ },
// Convert to native SVGMatrix
- , native: function() {
+ native: function () {
// create new matrix
var matrix = SVG.parser.nodes.svg.node.createSVGMatrix()
// update with current values
- for (var i = abcdef.length - 1; i >= 0; i--)
+ for (var i = abcdef.length - 1; i >= 0; i--) {
matrix[abcdef[i]] = this[abcdef[i]]
+ }
return matrix
- }
+ },
// Convert matrix to string
- , toString: function() {
+ toString: function () {
return 'matrix(' + this.a + ',' + this.b + ',' + this.c + ',' + this.d + ',' + this.e + ',' + this.f + ')'
}
- }
+ },
// Define parent
-, parent: SVG.Element
+ parent: SVG.Element,
// Add parent method
-, construct: {
+ construct: {
// Get current matrix
- ctm: function() {
+ ctm: function () {
return new SVG.Matrix(this.node.getCTM())
},
// Get current screen matrix
- screenCTM: function() {
+ screenCTM: function () {
/* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537
This is needed because FF does not return the transformation matrix
for the inner coordinate system when getScreenCTM() is called on nested svgs.
However all other Browsers do that */
- if(this instanceof SVG.Nested) {
- var rect = this.rect(1,1)
+ if (this instanceof SVG.Nested) {
+ var rect = this.rect(1, 1)
var m = rect.node.getScreenCTM()
rect.remove()
return new SVG.Matrix(m)
}
return new SVG.Matrix(this.node.getScreenCTM())
}
-
}
-
})
diff --git a/src/memory.js b/src/memory.js
index 1a30faa..57dfa02 100644
--- a/src/memory.js
+++ b/src/memory.js
@@ -1,36 +1,37 @@
+
SVG.extend(SVG.Element, {
// Remember arbitrary data
- remember: function(k, v) {
- // remember every item in an object individually
- if (typeof arguments[0] == 'object')
- for (var v in k)
- this.remember(v, k[v])
-
- // retrieve memory
- else if (arguments.length == 1)
+ remember: function (k, v) {
+ // remember every item in an object individually
+ if (typeof arguments[0] === 'object') {
+ for (var key in k) {
+ this.remember(key, k[key])
+ }
+ } else if (arguments.length === 1) {
+ // retrieve memory
return this.memory()[k]
-
- // store memory
- else
+ } else {
+ // store memory
this.memory()[k] = v
+ }
return this
- }
+ },
// Erase a given memory
-, forget: function() {
- if (arguments.length == 0)
+ forget: function () {
+ if (arguments.length === 0) {
this._memory = {}
- else
- for (var i = arguments.length - 1; i >= 0; i--)
+ } else {
+ for (var i = arguments.length - 1; i >= 0; i--) {
delete this.memory()[arguments[i]]
-
+ }
+ }
return this
- }
+ },
// Initialize or return local memory object
-, memory: function() {
+ memory: function () {
return this._memory || (this._memory = {})
}
-
-}) \ No newline at end of file
+})
diff --git a/src/nested.js b/src/nested.js
index bb328cc..217d59a 100644
--- a/src/nested.js
+++ b/src/nested.js
@@ -1,15 +1,16 @@
+
SVG.Nested = SVG.invent({
// Initialize node
- create: 'svg'
+ create: 'svg',
// Inherit from
-, inherit: SVG.Container
-
+ inherit: SVG.Container,
+
// Add parent method
-, construct: {
+ construct: {
// Create nested svg document
- nested: function() {
- return this.put(new SVG.Nested)
+ nested: function () {
+ return this.put(new SVG.Nested())
}
}
})
diff --git a/src/number.js b/src/number.js
index 8198e7c..6413f94 100644
--- a/src/number.js
+++ b/src/number.js
@@ -1,16 +1,16 @@
+
// Module for unit convertions
SVG.Number = SVG.invent({
// Initialize
- create: function(value, unit) {
+ create: function (value, unit) {
// initialize defaults
this.value = 0
- this.unit = unit || ''
+ this.unit = unit || ''
// parse value
if (typeof value === 'number') {
// ensure a valid numeric value
this.value = isNaN(value) ? 0 : !isFinite(value) ? (value < 0 ? -3.4e+38 : +3.4e+38) : value
-
} else if (typeof value === 'string') {
unit = value.match(SVG.regex.numberAndUnit)
@@ -19,83 +19,77 @@ SVG.Number = SVG.invent({
this.value = parseFloat(unit[1])
// normalize
- if (unit[5] == '%')
- this.value /= 100
- else if (unit[5] == 's')
+ if (unit[5] === '%') { this.value /= 100 } else if (unit[5] === 's') {
this.value *= 1000
+ }
// store unit
this.unit = unit[5]
}
-
} else {
if (value instanceof SVG.Number) {
this.value = value.valueOf()
- this.unit = value.unit
+ this.unit = value.unit
}
}
-
- }
+ },
// Add methods
-, extend: {
+ extend: {
// Stringalize
- toString: function() {
- return (
- this.unit == '%' ?
- ~~(this.value * 1e8) / 1e6:
- this.unit == 's' ?
- this.value / 1e3 :
- this.value
+ toString: function () {
+ return (this.unit === '%' ? ~~(this.value * 1e8) / 1e6
+ : this.unit === 's' ? this.value / 1e3
+ : this.value
) + this.unit
- }
- , toJSON: function() {
+ },
+ toJSON: function () {
return this.toString()
- }
- , // Convert to primitive
- valueOf: function() {
+ }, // Convert to primitive
+ valueOf: function () {
return this.value
- }
+ },
// Add number
- , plus: function(number) {
+ plus: function (number) {
number = new SVG.Number(number)
return new SVG.Number(this + number, this.unit || number.unit)
- }
+ },
// Subtract number
- , minus: function(number) {
+ minus: function (number) {
number = new SVG.Number(number)
return new SVG.Number(this - number, this.unit || number.unit)
- }
+ },
// Multiply number
- , times: function(number) {
+ times: function (number) {
number = new SVG.Number(number)
return new SVG.Number(this * number, this.unit || number.unit)
- }
+ },
// Divide number
- , divide: function(number) {
+ divide: function (number) {
number = new SVG.Number(number)
return new SVG.Number(this / number, this.unit || number.unit)
- }
+ },
// Convert to different unit
- , to: function(unit) {
+ to: function (unit) {
var number = new SVG.Number(this)
- if (typeof unit === 'string')
+ if (typeof unit === 'string') {
number.unit = unit
+ }
return number
- }
+ },
// Make number morphable
- , morph: function(number) {
+ morph: function (number) {
this.destination = new SVG.Number(number)
- if(number.relative) {
+ if (number.relative) {
this.destination.value += this.value
}
return this
- }
+ },
// Get morphed number at given position
- , at: function(pos) {
+ at: function (pos) {
// Make sure a destination is defined
if (!this.destination) return this
diff --git a/src/parent.js b/src/parent.js
index f8b6ee1..0ff1765 100644
--- a/src/parent.js
+++ b/src/parent.js
@@ -1,82 +1,88 @@
+/* global createElement */
+
SVG.Parent = SVG.invent({
// Initialize node
- create: function(node) {
- this.constructor.call(this, node)
- }
+ create: function (node) {
+ this.constructor(node)
+ },
// Inherit from
-, inherit: SVG.Element
+ inherit: SVG.Element,
// Add class methods
-, extend: {
+ extend: {
// Returns all child elements
- children: function() {
- return SVG.utils.map(this.node.children, function(node) {
+ children: function () {
+ return SVG.utils.map(this.node.children, function (node) {
return SVG.adopt(node)
})
- }
+ },
// Add given element at a position
- , add: function(element, i) {
+ add: function (element, i) {
element = createElement(element)
- if (i == null)
+ if (i == null) {
this.node.appendChild(element.node)
- else if (element.node != this.node.children[i])
+ } else if (element.node !== this.node.children[i]) {
this.node.insertBefore(element.node, this.node.children[i])
+ }
return this
- }
+ },
// Basically does the same as `add()` but returns the added element instead
- , put: function(element, i) {
+ put: function (element, i) {
this.add(element, i)
return element.instance || element
- }
+ },
// Checks if the given element is a child
- , has: function(element) {
+ has: function (element) {
return this.index(element) >= 0
- }
+ },
// Gets index of given element
- , index: function(element) {
+ index: function (element) {
return [].slice.call(this.node.children).indexOf(element.node)
- }
+ },
// Get a element at the given index
- , get: function(i) {
+ get: function (i) {
return SVG.adopt(this.node.children[i])
- }
+ },
// Get first child
- , first: function() {
+ first: function () {
return this.get(0)
- }
+ },
// Get the last child
- , last: function() {
+ last: function () {
return this.get(this.node.children.length - 1)
- }
+ },
// Iterates over all children and invokes a given block
- , each: function(block, deep) {
+ each: function (block, deep) {
+ var children = this.children()
var i, il
- , children = this.children()
for (i = 0, il = children.length; i < il; i++) {
- if (children[i] instanceof SVG.Element)
+ if (children[i] instanceof SVG.Element) {
block.apply(children[i], [i, children])
+ }
- if (deep && (children[i] instanceof SVG.Parent))
+ if (deep && (children[i] instanceof SVG.Parent)) {
children[i].each(block, deep)
+ }
}
return this
- }
+ },
// Remove a given child
- , removeElement: function(element) {
+ removeElement: function (element) {
this.node.removeChild(element.node)
return this
- }
+ },
// Remove all elements in this container
- , clear: function() {
+ clear: function () {
// remove children
- while(this.node.hasChildNodes())
+ while (this.node.hasChildNodes()) {
this.node.removeChild(this.node.lastChild)
+ }
// remove defs reference
delete this._defs
diff --git a/src/parser.js b/src/parser.js
index 6988807..c3ab7a4 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -1,7 +1,8 @@
-SVG.parser = function() {
+
+SVG.parser = function () {
var b
- if(!SVG.parser.nodes.svg.node.parentNode) {
+ if (!SVG.parser.nodes.svg.node.parentNode) {
b = document.body || document.documentElement
SVG.parser.nodes.svg.addTo(b)
}
@@ -11,11 +12,11 @@ SVG.parser = function() {
SVG.parser.nodes = {
svg: new SVG.Nested().size(2, 0).css({
- opacity:0,
- position:'absolute',
- left:'-100%',
- top:'-100%',
- overflow:'hidden'
+ opacity: 0,
+ position: 'absolute',
+ left: '-100%',
+ top: '-100%',
+ overflow: 'hidden'
})
}
diff --git a/src/path.js b/src/path.js
index 84392a2..db3929b 100644
--- a/src/path.js
+++ b/src/path.js
@@ -1,63 +1,63 @@
+/* global proportionalSize */
+
SVG.Path = SVG.invent({
// Initialize node
- create: 'path'
+ create: 'path',
// Inherit from
-, inherit: SVG.Shape
+ inherit: SVG.Shape,
// Add class methods
-, extend: {
+ extend: {
// Define morphable array
- morphArray: SVG.PathArray
+ MorphArray: SVG.PathArray,
// Get array
- , array: function() {
+ array: function () {
return this._array || (this._array = new SVG.PathArray(this.attr('d')))
- }
+ },
// Plot new path
- , plot: function(d) {
- return (d == null) ?
- this.array() :
- this.clear().attr('d', typeof d == 'string' ? d : (this._array = new SVG.PathArray(d)))
- }
+ plot: function (d) {
+ return (d == null) ? this.array()
+ : this.clear().attr('d', typeof d === 'string' ? d : (this._array = new SVG.PathArray(d)))
+ },
// Clear array cache
- , clear: function() {
+ clear: function () {
delete this._array
return this
- }
+ },
// Move by left top corner
- , move: function(x, y) {
+ move: function (x, y) {
return this.attr('d', this.array().move(x, y))
- }
+ },
// Move by left top corner over x-axis
- , x: function(x) {
+ 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) {
+ 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) {
+ size: function (width, height) {
var p = proportionalSize(this, width, height)
-
return this.attr('d', this.array().size(p.width, p.height))
- }
+ },
// Set width of element
- , width: function(width) {
+ width: function (width) {
return width == null ? this.bbox().width : this.size(width, this.bbox().height)
- }
+ },
// Set height of element
- , height: function(height) {
+ height: function (height) {
return height == null ? this.bbox().height : this.size(this.bbox().width, height)
}
- }
+ },
// Add parent method
-, construct: {
+ construct: {
// Create a wrapped path element
- path: function(d) {
+ path: function (d) {
// make sure plot is called as a setter
- return this.put(new SVG.Path).plot(d || new SVG.PathArray)
+ return this.put(new SVG.Path()).plot(d || new SVG.PathArray())
}
}
})
diff --git a/src/patharray.js b/src/patharray.js
index 697bc68..d9ffecd 100644
--- a/src/patharray.js
+++ b/src/patharray.js
@@ -1,49 +1,51 @@
+/* globals arrayToString, pathRegReplace */
+
var pathHandlers = {
- M: function(c, p, p0) {
+ M: function (c, p, p0) {
p.x = p0.x = c[0]
p.y = p0.y = c[1]
return ['M', p.x, p.y]
},
- L: function(c, p) {
+ L: function (c, p) {
p.x = c[0]
p.y = c[1]
return ['L', c[0], c[1]]
},
- H: function(c, p) {
+ H: function (c, p) {
p.x = c[0]
return ['H', c[0]]
},
- V: function(c, p) {
+ V: function (c, p) {
p.y = c[0]
return ['V', c[0]]
},
- C: function(c, p) {
+ C: function (c, p) {
p.x = c[4]
p.y = c[5]
return ['C', c[0], c[1], c[2], c[3], c[4], c[5]]
},
- S: function(c, p) {
+ S: function (c, p) {
p.x = c[2]
p.y = c[3]
return ['S', c[0], c[1], c[2], c[3]]
},
- Q: function(c, p) {
+ Q: function (c, p) {
p.x = c[2]
p.y = c[3]
return ['Q', c[0], c[1], c[2], c[3]]
},
- T: function(c, p) {
+ T: function (c, p) {
p.x = c[0]
p.y = c[1]
return ['T', c[0], c[1]]
},
- Z: function(c, p, p0) {
+ Z: function (c, p, p0) {
p.x = p0.x
p.y = p0.y
return ['Z']
},
- A: function(c, p) {
+ A: function (c, p) {
p.x = c[5]
p.y = c[6]
return ['A', c[0], c[1], c[2], c[3], c[4], c[5], c[6]]
@@ -52,19 +54,19 @@ var pathHandlers = {
var mlhvqtcsaz = 'mlhvqtcsaz'.split('')
-for(var i = 0, il = mlhvqtcsaz.length; i < il; ++i){
- pathHandlers[mlhvqtcsaz[i]] = (function(i){
- return function(c, p, p0) {
- if(i == 'H') c[0] = c[0] + p.x
- else if(i == 'V') c[0] = c[0] + p.y
- else if(i == 'A'){
- c[5] = c[5] + p.x,
+for (var i = 0, il = mlhvqtcsaz.length; i < il; ++i) {
+ pathHandlers[mlhvqtcsaz[i]] = (function (i) {
+ return function (c, p, p0) {
+ if (i === 'H') c[0] = c[0] + p.x
+ else if (i === 'V') c[0] = c[0] + p.y
+ else if (i === 'A') {
+ c[5] = c[5] + p.x
c[6] = c[6] + p.y
- }
- else
- for(var j = 0, jl = c.length; j < jl; ++j) {
- c[j] = c[j] + (j%2 ? p.y : p.x)
+ } else {
+ for (var j = 0, jl = c.length; j < jl; ++j) {
+ c[j] = c[j] + (j % 2 ? p.y : p.x)
}
+ }
return pathHandlers[i](c, p, p0)
}
@@ -72,21 +74,21 @@ for(var i = 0, il = mlhvqtcsaz.length; i < il; ++i){
}
// Path points array
-SVG.PathArray = function(array, fallback) {
+SVG.PathArray = function (array, fallback) {
SVG.Array.call(this, array, fallback || [['M', 0, 0]])
}
// Inherit from SVG.Array
-SVG.PathArray.prototype = new SVG.Array
+SVG.PathArray.prototype = new SVG.Array()
SVG.PathArray.prototype.constructor = SVG.PathArray
SVG.extend(SVG.PathArray, {
// Convert array to string
- toString: function() {
+ toString: function () {
return arrayToString(this.value)
- }
+ },
// Move path string
-, move: function(x, y) {
+ move: function (x, y) {
// get bounding box of current situation
var box = this.bbox()
@@ -99,121 +101,113 @@ SVG.extend(SVG.PathArray, {
for (var l, i = this.value.length - 1; i >= 0; i--) {
l = this.value[i][0]
- if (l == 'M' || l == 'L' || l == 'T') {
+ if (l === 'M' || l === 'L' || l === 'T') {
this.value[i][1] += x
this.value[i][2] += y
-
- } else if (l == 'H') {
+ } else if (l === 'H') {
this.value[i][1] += x
-
- } else if (l == 'V') {
+ } else if (l === 'V') {
this.value[i][1] += y
-
- } else if (l == 'C' || l == 'S' || l == 'Q') {
+ } else if (l === 'C' || l === 'S' || l === 'Q') {
this.value[i][1] += x
this.value[i][2] += y
this.value[i][3] += x
this.value[i][4] += y
- if (l == 'C') {
+ if (l === 'C') {
this.value[i][5] += x
this.value[i][6] += y
}
-
- } else if (l == 'A') {
+ } else if (l === 'A') {
this.value[i][6] += x
this.value[i][7] += y
}
-
}
}
return this
- }
+ },
// Resize path string
-, size: function(width, height) {
+ size: function (width, height) {
// get bounding box of current situation
- var i, l, box = this.bbox()
+ var box = this.bbox()
+ var i, l
// recalculate position of all points according to new size
for (i = this.value.length - 1; i >= 0; i--) {
l = this.value[i][0]
- if (l == 'M' || l == 'L' || l == 'T') {
- this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
+ if (l === 'M' || l === 'L' || l === 'T') {
+ this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
this.value[i][2] = ((this.value[i][2] - box.y) * height) / box.height + box.y
-
- } else if (l == 'H') {
- this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
-
- } else if (l == 'V') {
+ } else if (l === 'H') {
+ this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
+ } else if (l === 'V') {
this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y
-
- } else if (l == 'C' || l == 'S' || l == 'Q') {
- this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
+ } else if (l === 'C' || l === 'S' || l === 'Q') {
+ this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x
this.value[i][2] = ((this.value[i][2] - box.y) * height) / box.height + box.y
- this.value[i][3] = ((this.value[i][3] - box.x) * width) / box.width + box.x
+ this.value[i][3] = ((this.value[i][3] - box.x) * width) / box.width + box.x
this.value[i][4] = ((this.value[i][4] - box.y) * height) / box.height + box.y
- if (l == 'C') {
- this.value[i][5] = ((this.value[i][5] - box.x) * width) / box.width + box.x
+ if (l === 'C') {
+ this.value[i][5] = ((this.value[i][5] - box.x) * width) / box.width + box.x
this.value[i][6] = ((this.value[i][6] - box.y) * height) / box.height + box.y
}
-
- } else if (l == 'A') {
+ } else if (l === 'A') {
// resize radii
- this.value[i][1] = (this.value[i][1] * width) / box.width
+ this.value[i][1] = (this.value[i][1] * width) / box.width
this.value[i][2] = (this.value[i][2] * height) / box.height
// move position values
- this.value[i][6] = ((this.value[i][6] - box.x) * width) / box.width + box.x
+ this.value[i][6] = ((this.value[i][6] - box.x) * width) / box.width + box.x
this.value[i][7] = ((this.value[i][7] - box.y) * height) / box.height + box.y
}
-
}
return this
- }
+ },
// Test if the passed path array use the same path data commands as this path array
-, equalCommands: function(pathArray) {
+ equalCommands: function (pathArray) {
var i, il, equalCommands
pathArray = new SVG.PathArray(pathArray)
equalCommands = this.value.length === pathArray.value.length
- for(i = 0, il = this.value.length; equalCommands && i < il; i++) {
+ for (i = 0, il = this.value.length; equalCommands && i < il; i++) {
equalCommands = this.value[i][0] === pathArray.value[i][0]
}
return equalCommands
- }
+ },
// Make path array morphable
-, morph: function(pathArray) {
+ morph: function (pathArray) {
pathArray = new SVG.PathArray(pathArray)
- if(this.equalCommands(pathArray)) {
+ if (this.equalCommands(pathArray)) {
this.destination = pathArray
} else {
this.destination = null
}
return this
- }
+ },
// Get morphed path array at given position
-, at: function(pos) {
+ at: function (pos) {
// make sure a destination is defined
if (!this.destination) return this
var sourceArray = this.value
- , destinationArray = this.destination.value
- , array = [], pathArray = new SVG.PathArray()
- , i, il, j, jl
+ var destinationArray = this.destination.value
+ var array = []
+ var pathArray = new SVG.PathArray()
+ var i, il, j, jl
// Animate has specified in the SVG spec
// See: https://www.w3.org/TR/SVG11/paths.html#PathElement
for (i = 0, il = sourceArray.length; i < il; i++) {
array[i] = [sourceArray[i][0]]
- for(j = 1, jl = sourceArray[i].length; j < jl; j++) {
+ for (j = 1, jl = sourceArray[i].length; j < jl; j++) {
array[i][j] = sourceArray[i][j] + (destinationArray[i][j] - sourceArray[i][j]) * pos
}
// For the two flags of the elliptical arc command, the SVG spec say:
@@ -221,74 +215,68 @@ SVG.extend(SVG.PathArray, {
// Elliptical arc command as an array followed by corresponding indexes:
// ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y]
// 0 1 2 3 4 5 6 7
- if(array[i][0] === 'A') {
- array[i][4] = +(array[i][4] != 0)
- array[i][5] = +(array[i][5] != 0)
+ if (array[i][0] === 'A') {
+ array[i][4] = +(array[i][4] !== 0)
+ array[i][5] = +(array[i][5] !== 0)
}
}
// Directly modify the value of a path array, this is done this way for performance
pathArray.value = array
return pathArray
- }
+ },
// Absolutize and parse path to array
-, parse: function(array) {
+ parse: function (array) {
// if it's already a patharray, no need to parse it
if (array instanceof SVG.PathArray) return array.valueOf()
// prepare for parsing
- var i, x0, y0, s, seg, arr
- , x = 0
- , y = 0
- , paramCnt = { 'M':2, 'L':2, 'H':1, 'V':1, 'C':6, 'S':4, 'Q':4, 'T':2, 'A':7, 'Z':0 }
-
- if(typeof array == 'string'){
+ var s
+ var paramCnt = { 'M': 2, 'L': 2, 'H': 1, 'V': 1, 'C': 6, 'S': 4, 'Q': 4, 'T': 2, 'A': 7, 'Z': 0 }
+ if (typeof array === 'string') {
array = array
.replace(SVG.regex.numbersWithDots, pathRegReplace) // convert 45.123.123 to 45.123 .123
.replace(SVG.regex.pathLetters, ' $& ') // put some room between letters and numbers
.replace(SVG.regex.hyphen, '$1 -') // add space before hyphen
.trim() // trim
.split(SVG.regex.delimiter) // split into array
-
- }else{
- array = array.reduce(function(prev, curr){
+ } else {
+ array = array.reduce(function (prev, curr) {
return [].concat.call(prev, curr)
}, [])
}
// array now is an array containing all parts of a path e.g. ['M', '0', '0', 'L', '30', '30' ...]
- var arr = []
- , p = new SVG.Point()
- , p0 = new SVG.Point()
- , index = 0
- , len = array.length
+ var result = []
+ var p = new SVG.Point()
+ var p0 = new SVG.Point()
+ var index = 0
+ var len = array.length
- do{
+ do {
// Test if we have a path letter
- if(SVG.regex.isPathLetter.test(array[index])){
+ if (SVG.regex.isPathLetter.test(array[index])) {
s = array[index]
++index
// If last letter was a move command and we got no new, it defaults to [L]ine
- }else if(s == 'M'){
+ } else if (s === 'M') {
s = 'L'
- }else if(s == 'm'){
+ } else if (s === 'm') {
s = 'l'
}
- arr.push(pathHandlers[s].call(null,
+ result.push(pathHandlers[s].call(null,
array.slice(index, (index = index + paramCnt[s.toUpperCase()])).map(parseFloat),
p, p0
)
)
+ } while (len > index)
- }while(len > index)
-
- return arr
-
- }
+ return result
+ },
// Get bounding box of path
-, bbox: function() {
+ bbox: function () {
SVG.parser().path.setAttribute('d', this.toString())
return SVG.parser.nodes.path.getBBox()
}
diff --git a/src/pattern.js b/src/pattern.js
index cae0958..d4c4116 100644
--- a/src/pattern.js
+++ b/src/pattern.js
@@ -1,43 +1,44 @@
SVG.Pattern = SVG.invent({
// Initialize node
- create: 'pattern'
+ create: 'pattern',
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
// Add class methods
-, extend: {
+ extend: {
// Return the fill id
- url: function() {
+ url: function () {
return 'url(#' + this.id() + ')'
- }
+ },
// Update pattern by rebuilding
- , update: function(block) {
+ update: function (block) {
// remove content
this.clear()
-
+
// invoke passed block
- if (typeof block == 'function')
+ if (typeof block === 'function') {
block.call(this, this)
-
+ }
+
return this
- }
+ },
// Alias string convertion to fill
- , toString: function() {
+ toString: function () {
return this.url()
- }
+ },
// custom attr to handle transform
- , attr: function(a, b, c) {
- if(a == 'transform') a = 'patternTransform'
+ attr: function (a, b, c) {
+ if (a === 'transform') a = 'patternTransform'
return SVG.Container.prototype.attr.call(this, a, b, c)
}
- }
-
+ },
+
// Add parent method
-, construct: {
+ construct: {
// Create pattern element in defs
- pattern: function(width, height, block) {
+ pattern: function (width, height, block) {
return this.defs().pattern(width, height, block)
}
}
@@ -45,14 +46,14 @@ SVG.Pattern = SVG.invent({
SVG.extend(SVG.Defs, {
// Define gradient
- pattern: function(width, height, block) {
- return this.put(new SVG.Pattern).update(block).attr({
- x: 0
- , y: 0
- , width: width
- , height: height
- , patternUnits: 'userSpaceOnUse'
+ pattern: function (width, height, block) {
+ return this.put(new SVG.Pattern()).update(block).attr({
+ x: 0,
+ y: 0,
+ width: width,
+ height: height,
+ patternUnits: 'userSpaceOnUse'
})
}
-}) \ No newline at end of file
+})
diff --git a/src/point.js b/src/point.js
index 2ae2271..682092e 100644
--- a/src/point.js
+++ b/src/point.js
@@ -1,49 +1,49 @@
+
SVG.Point = SVG.invent({
// Initialize
- create: function(x,y) {
- var i, source, base = {x:0, y:0}
+ create: function (x, y) {
+ var base = {x: 0, y: 0}
+ var source
// ensure source as object
- source = Array.isArray(x) ?
- {x:x[0], y:x[1]} :
- typeof x === 'object' ?
- {x:x.x, y:x.y} :
- x != null ?
- {x:x, y:(y != null ? y : x)} : base // If y has no value, then x is used has its value
+ source = Array.isArray(x) ? {x: x[0], y: x[1]}
+ : typeof x === 'object' ? {x: x.x, y: x.y}
+ : x != null ? {x: x, y: (y != null ? y : x)}
+ : base // If y has no value, then x is used has its value
// merge source
this.x = source.x
this.y = source.y
- }
+ },
// Add methods
-, extend: {
+ extend: {
// Clone point
- clone: function() {
+ clone: function () {
return new SVG.Point(this)
- }
+ },
// Morph one point into another
- , morph: function(x, y) {
+ morph: function (x, y) {
// store new destination
this.destination = new SVG.Point(x, y)
return this
- }
+ },
// Get morphed point at a given position
- , at: function(pos) {
+ at: function (pos) {
// make sure a destination is defined
if (!this.destination) return this
// calculate morphed matrix at a given position
var point = new SVG.Point({
- x: this.x + (this.destination.x - this.x) * pos
- , y: this.y + (this.destination.y - this.y) * pos
+ x: this.x + (this.destination.x - this.x) * pos,
+ y: this.y + (this.destination.y - this.y) * pos
})
return point
- }
+ },
// Convert to native SVGPoint
- , native: function() {
+ native: function () {
// create new point
var point = SVG.parser.nodes.svg.node.createSVGPoint()
@@ -52,21 +52,19 @@ SVG.Point = SVG.invent({
point.y = this.y
return point
- }
+ },
// transform point with matrix
- , transform: function(matrix) {
+ transform: function (matrix) {
return new SVG.Point(this.native().matrixTransform(matrix.native()))
}
-
}
-
})
SVG.extend(SVG.Element, {
// Get point
- point: function(x, y) {
- return new SVG.Point(x,y).transform(this.screenCTM().inverse());
+ point: function (x, y) {
+ return new SVG.Point(x, y).transform(this.screenCTM().inverse())
}
})
diff --git a/src/pointarray.js b/src/pointarray.js
index fca684f..ecf5c40 100644
--- a/src/pointarray.js
+++ b/src/pointarray.js
@@ -1,46 +1,52 @@
+
// Poly points array
-SVG.PointArray = function(array, fallback) {
- SVG.Array.call(this, array, fallback || [[0,0]])
+SVG.PointArray = function (array, fallback) {
+ SVG.Array.call(this, array, fallback || [[0, 0]])
}
// Inherit from SVG.Array
-SVG.PointArray.prototype = new SVG.Array
+SVG.PointArray.prototype = new SVG.Array()
SVG.PointArray.prototype.constructor = SVG.PointArray
SVG.extend(SVG.PointArray, {
// Convert array to string
- toString: function() {
+ toString: function () {
// convert to a poly point string
- for (var i = 0, il = this.value.length, array = []; i < il; i++)
+ for (var i = 0, il = this.value.length, array = []; i < il; i++) {
array.push(this.value[i].join(','))
+ }
return array.join(' ')
- }
+ },
+
// Convert array to line object
-, toLine: function() {
+ toLine: function () {
return {
- x1: this.value[0][0]
- , y1: this.value[0][1]
- , x2: this.value[1][0]
- , y2: this.value[1][1]
+ x1: this.value[0][0],
+ y1: this.value[0][1],
+ x2: this.value[1][0],
+ y2: this.value[1][1]
}
- }
+ },
+
// Get morphed array at given position
-, at: function(pos) {
+ at: function (pos) {
// make sure a destination is defined
if (!this.destination) return this
// generate morphed point string
- for (var i = 0, il = this.value.length, array = []; i < il; i++)
+ for (var i = 0, il = this.value.length, array = []; i < il; i++) {
array.push([
- this.value[i][0] + (this.destination[i][0] - this.value[i][0]) * pos
- , this.value[i][1] + (this.destination[i][1] - this.value[i][1]) * pos
+ this.value[i][0] + (this.destination[i][0] - this.value[i][0]) * pos,
+ this.value[i][1] + (this.destination[i][1] - this.value[i][1]) * pos
])
+ }
return new SVG.PointArray(array)
- }
+ },
+
// Parse point string and flat array
-, parse: function(array) {
+ parse: function (array) {
var points = []
array = array.valueOf()
@@ -48,7 +54,7 @@ SVG.extend(SVG.PointArray, {
// if it is an array
if (Array.isArray(array)) {
// and it is not flat, there is no need to parse it
- if(Array.isArray(array[0])) {
+ if (Array.isArray(array[0])) {
return array
}
} else { // Else, it is considered as a string
@@ -61,13 +67,15 @@ SVG.extend(SVG.PointArray, {
if (array.length % 2 !== 0) array.pop()
// wrap points in two-tuples and parse points as floats
- for(var i = 0, len = array.length; i < len; i = i + 2)
- points.push([ array[i], array[i+1] ])
+ for (var i = 0, len = array.length; i < len; i = i + 2) {
+ points.push([ array[i], array[i + 1] ])
+ }
return points
- }
+ },
+
// Move point string
-, move: function(x, y) {
+ move: function (x, y) {
var box = this.bbox()
// get relative offset
@@ -75,33 +83,40 @@ SVG.extend(SVG.PointArray, {
y -= box.y
// move every point
- if (!isNaN(x) && !isNaN(y))
- for (var i = this.value.length - 1; i >= 0; i--)
+ if (!isNaN(x) && !isNaN(y)) {
+ for (var i = this.value.length - 1; i >= 0; i--) {
this.value[i] = [this.value[i][0] + x, this.value[i][1] + y]
+ }
+ }
return this
- }
+ },
// Resize poly string
-, size: function(width, height) {
- var i, box = this.bbox()
+ size: function (width, height) {
+ var i
+ var box = this.bbox()
// recalculate position of all points according to new size
for (i = this.value.length - 1; i >= 0; i--) {
- if(box.width) this.value[i][0] = ((this.value[i][0] - box.x) * width) / box.width + box.x
- if(box.height) this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y
+ if (box.width) this.value[i][0] = ((this.value[i][0] - box.x) * width) / box.width + box.x
+ if (box.height) this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y
}
return this
- }
+ },
+
// Get bounding box of points
-, bbox: function() {
- var maxX = -Infinity, maxY = -Infinity, minX = Infinity, minY = Infinity
- this.value.forEach(function(el) {
+ bbox: function () {
+ var maxX = -Infinity
+ var maxY = -Infinity
+ var minX = Infinity
+ var minY = Infinity
+ this.value.forEach(function (el) {
maxX = Math.max(el[0], maxX)
maxY = Math.max(el[1], maxY)
minX = Math.min(el[0], minX)
minY = Math.min(el[1], minY)
})
- return {x: minX, y: minY, width: maxX-minX, height: maxY-minY}
+ return {x: minX, y: minY, width: maxX - minX, height: maxY - minY}
}
})
diff --git a/src/pointed.js b/src/pointed.js
index 9ef70d3..6493964 100644
--- a/src/pointed.js
+++ b/src/pointed.js
@@ -1,25 +1,25 @@
// unify all point to point elements
SVG.extend([SVG.Line, SVG.Polyline, SVG.Polygon], {
// Define morphable array
- morphArray: SVG.PointArray
+ MorphArray: SVG.PointArray,
// Move by left top corner over x-axis
-, x: function(x) {
+ 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) {
+ y: function (y) {
return y == null ? this.bbox().y : this.move(this.bbox().x, y)
- }
+ },
// Set width of element
-, width: function(width) {
+ width: function (width) {
var b = this.bbox()
return width == null ? b.width : this.size(width, b.height)
- }
+ },
// Set height of element
-, height: function(height) {
+ height: function (height) {
var b = this.bbox()
- return height == null ? b.height : this.size(b.width, height)
+ return height == null ? b.height : this.size(b.width, height)
}
-}) \ No newline at end of file
+})
diff --git a/src/poly.js b/src/poly.js
index ae86ac3..9625776 100644
--- a/src/poly.js
+++ b/src/poly.js
@@ -1,33 +1,35 @@
+/* global proportionalSize */
+
SVG.Polyline = SVG.invent({
// Initialize node
- create: 'polyline'
+ create: 'polyline',
// Inherit from
-, inherit: SVG.Shape
+ inherit: SVG.Shape,
// Add parent method
-, construct: {
+ construct: {
// Create a wrapped polyline element
- polyline: function(p) {
+ polyline: function (p) {
// make sure plot is called as a setter
- return this.put(new SVG.Polyline).plot(p || new SVG.PointArray)
+ return this.put(new SVG.Polyline()).plot(p || new SVG.PointArray())
}
}
})
SVG.Polygon = SVG.invent({
// Initialize node
- create: 'polygon'
+ create: 'polygon',
// Inherit from
-, inherit: SVG.Shape
+ inherit: SVG.Shape,
// Add parent method
-, construct: {
+ construct: {
// Create a wrapped polygon element
- polygon: function(p) {
+ polygon: function (p) {
// make sure plot is called as a setter
- return this.put(new SVG.Polygon).plot(p || new SVG.PointArray)
+ return this.put(new SVG.Polygon()).plot(p || new SVG.PointArray())
}
}
})
@@ -35,29 +37,31 @@ SVG.Polygon = SVG.invent({
// Add polygon-specific functions
SVG.extend([SVG.Polyline, SVG.Polygon], {
// Get array
- array: function() {
+ array: function () {
return this._array || (this._array = new SVG.PointArray(this.attr('points')))
- }
+ },
+
// Plot new path
-, plot: function(p) {
- return (p == null) ?
- this.array() :
- this.clear().attr('points', typeof p == 'string' ? p : (this._array = new SVG.PointArray(p)))
- }
+ plot: function (p) {
+ return (p == null) ? this.array()
+ : this.clear().attr('points', typeof p === 'string' ? p
+ : (this._array = new SVG.PointArray(p)))
+ },
+
// Clear array cache
-, clear: function() {
+ clear: function () {
delete this._array
return this
- }
+ },
+
// Move by left top corner
-, move: function(x, y) {
+ move: function (x, y) {
return this.attr('points', this.array().move(x, y))
- }
+ },
+
// Set element size to given width and height
-, size: function(width, height) {
+ size: function (width, height) {
var p = proportionalSize(this, width, height)
-
return this.attr('points', this.array().size(p.width, p.height))
}
-
})
diff --git a/src/rect.js b/src/rect.js
index 6c639fe..35a3678 100644
--- a/src/rect.js
+++ b/src/rect.js
@@ -1,15 +1,16 @@
+
SVG.Rect = SVG.invent({
// Initialize node
- create: 'rect'
+ create: 'rect',
// Inherit from
-, inherit: SVG.Shape
-
+ inherit: SVG.Shape,
+
// Add parent method
-, construct: {
+ construct: {
// Create a rect element
- rect: function(width, height) {
+ rect: function (width, height) {
return this.put(new SVG.Rect()).size(width, height)
}
}
-}) \ No newline at end of file
+})
diff --git a/src/regex.js b/src/regex.js
index c0ca706..5a3e3eb 100644
--- a/src/regex.js
+++ b/src/regex.js
@@ -1,61 +1,61 @@
// Storage for regular expressions
SVG.regex = {
// Parse unit value
- numberAndUnit: /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i
+ numberAndUnit: /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,
// Parse hex value
-, hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i
+ hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,
// Parse rgb value
-, rgb: /rgb\((\d+),(\d+),(\d+)\)/
+ rgb: /rgb\((\d+),(\d+),(\d+)\)/,
// Parse reference id
-, reference: /#([a-z0-9\-_]+)/i
+ reference: /#([a-z0-9\-_]+)/i,
// splits a transformation chain
-, transforms: /\)\s*,?\s*/
+ transforms: /\)\s*,?\s*/,
// Whitespace
-, whitespace: /\s/g
+ whitespace: /\s/g,
// Test hex value
-, isHex: /^#[a-f0-9]{3,6}$/i
+ isHex: /^#[a-f0-9]{3,6}$/i,
// Test rgb value
-, isRgb: /^rgb\(/
+ isRgb: /^rgb\(/,
// Test css declaration
-, isCss: /[^:]+:[^;]+;?/
+ isCss: /[^:]+:[^;]+;?/,
// Test for blank string
-, isBlank: /^(\s+)?$/
+ isBlank: /^(\s+)?$/,
// Test for numeric string
-, isNumber: /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i
+ isNumber: /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
// Test for percent value
-, isPercent: /^-?[\d\.]+%$/
+ isPercent: /^-?[\d.]+%$/,
// Test for image url
-, isImage: /\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i
+ isImage: /\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,
// split at whitespace and comma
-, delimiter: /[\s,]+/
+ delimiter: /[\s,]+/,
// The following regex are used to parse the d attribute of a path
// Matches all hyphens which are not after an exponent
-, hyphen: /([^e])\-/gi
+ hyphen: /([^e])-/gi,
// Replaces and tests for all path letters
-, pathLetters: /[MLHVCSQTAZ]/gi
+ pathLetters: /[MLHVCSQTAZ]/gi,
// yes we need this one, too
-, isPathLetter: /[MLHVCSQTAZ]/i
+ isPathLetter: /[MLHVCSQTAZ]/i,
// matches 0.154.23.45
-, numbersWithDots: /((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi
+ numbersWithDots: /((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi,
// matches .
-, dots: /\./g
+ dots: /\./g
}
diff --git a/src/selector.js b/src/selector.js
index afe006d..b4ea05f 100644
--- a/src/selector.js
+++ b/src/selector.js
@@ -1,29 +1,31 @@
+/* global idFromReference */
+
// Method for getting an element by id
-SVG.get = function(id) {
+SVG.get = function (id) {
var node = document.getElementById(idFromReference(id) || id)
return SVG.adopt(node)
}
// Select elements by query string
-SVG.select = function(query, parent) {
- return SVG.utils.map((parent || document).querySelectorAll(query), function(node) {
+SVG.select = function (query, parent) {
+ return SVG.utils.map((parent || document).querySelectorAll(query), function (node) {
return SVG.adopt(node)
})
}
-SVG.$$ = function(query, parent) {
- return SVG.utils.map((parent || document).querySelectorAll(query), function(node) {
+SVG.$$ = function (query, parent) {
+ return SVG.utils.map((parent || document).querySelectorAll(query), function (node) {
return SVG.adopt(node)
})
}
-SVG.$ = function(query, parent) {
+SVG.$ = function (query, parent) {
return SVG.adopt((parent || document).querySelector(query))
}
SVG.extend(SVG.Parent, {
// Scoped select method
- select: function(query) {
+ select: function (query) {
return SVG.select(query, this.node)
}
})
diff --git a/src/shape.js b/src/shape.js
index 0f7b954..87b01f9 100644
--- a/src/shape.js
+++ b/src/shape.js
@@ -1,10 +1,10 @@
+
SVG.Shape = SVG.invent({
// Initialize node
- create: function(node) {
- this.constructor.call(this, node)
- }
+ create: function (node) {
+ this.constructor(node)
+ },
// Inherit from
-, inherit: SVG.Element
-
+ inherit: SVG.Element
})
diff --git a/src/sugar.js b/src/sugar.js
index 838592c..7c555da 100644
--- a/src/sugar.js
+++ b/src/sugar.js
@@ -1,42 +1,45 @@
// Define list of available attributes for stroke and fill
var sugar = {
- stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset']
-, fill: ['color', 'opacity', 'rule']
-, prefix: function(t, a) {
- return a == 'color' ? t : t + '-' + a
+ stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset'],
+ fill: ['color', 'opacity', 'rule'],
+ prefix: function (t, a) {
+ return a === 'color' ? t : t + '-' + a
}
}
// Add sugar for fill and stroke
-;['fill', 'stroke'].forEach(function(m) {
- var i, extension = {}
+;['fill', 'stroke'].forEach(function (m) {
+ var extension = {}
+ var i
- extension[m] = function(o) {
- if (typeof o == 'undefined')
+ extension[m] = function (o) {
+ if (typeof o === 'undefined') {
return this
- if (typeof o == 'string' || SVG.Color.isRgb(o) || (o && typeof o.fill === 'function'))
+ }
+ if (typeof o === 'string' || SVG.Color.isRgb(o) || (o && typeof o.fill === 'function')) {
this.attr(m, o)
-
- else
+ } else {
// set all attributes from sugar.fill and sugar.stroke list
- for (i = sugar[m].length - 1; i >= 0; i--)
- if (o[sugar[m][i]] != null)
+ for (i = sugar[m].length - 1; i >= 0; i--) {
+ if (o[sugar[m][i]] != null) {
this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]])
+ }
+ }
+ }
return this
}
SVG.extend([SVG.Element, SVG.FX], extension)
-
})
SVG.extend([SVG.Element, SVG.FX], {
// Map rotation to transform
, rotate: function(angle, cx, cy) {
var matrix = new SVG.Matrix().rotate(angle, cx, cy)
-
+
return this.transform({ rotation: d, cx: cx, cy: cy })
- }
+ },
// Map skew to transform
, skew: function(x, y, cx, cy) {
return arguments.length == 1 || arguments.length == 3 ?
@@ -44,72 +47,72 @@ SVG.extend([SVG.Element, SVG.FX], {
this.transform({ skewX: x, skewY: y, cx: cx, cy: cy })
}
// Map scale to transform
-, scale: function(x, y, cx, cy) {
- return arguments.length == 1 || arguments.length == 3 ?
- this.transform({ scale: x, cx: y, cy: cx }) :
- this.transform({ scaleX: x, scaleY: y, cx: cx, cy: cy })
- }
+ scale: function (x, y, cx, cy) {
+ return arguments.length === 1 || arguments.length === 3
+ ? this.transform({ scale: x, cx: y, cy: cx })
+ : this.transform({ scaleX: x, scaleY: y, cx: cx, cy: cy })
+ },
// Map translate to transform
-, translate: function(x, y) {
+ translate: function (x, y) {
return this.transform({ x: x, y: y })
- }
+ },
// Map flip to transform
-, flip: function(a, o) {
- o = typeof a == 'number' ? a : o
+ flip: function (a, o) {
+ o = typeof a === 'number' ? a : o
return this.transform({ flip: a || 'both', offset: o })
}
// Opacity
-, opacity: function(value) {
+ opacity: function (value) {
return this.attr('opacity', value)
- }
+ },
// Relative move over x axis
-, dx: function(x) {
+ dx: function (x) {
return this.x(new SVG.Number(x).plus(this instanceof SVG.FX ? 0 : this.x()), true)
- }
+ },
// Relative move over y axis
-, dy: function(y) {
+ dy: function (y) {
return this.y(new SVG.Number(y).plus(this instanceof SVG.FX ? 0 : this.y()), true)
- }
+ },
// Relative move over x and y axes
-, dmove: function(x, y) {
+ dmove: function (x, y) {
return this.dx(x).dy(y)
}
})
SVG.extend([SVG.Rect, SVG.Ellipse, SVG.Circle, SVG.Gradient, SVG.FX], {
// Add x and y radius
- radius: function(x, y) {
- var type = (this._target || this).type;
- return type == 'radialGradient' || type == 'radialGradient' ?
- this.attr('r', new SVG.Number(x)) :
- this.rx(x).ry(y == null ? x : y)
+ radius: function (x, y) {
+ var type = (this._target || this).type
+ return type === 'radialGradient' || type === 'radialGradient'
+ ? this.attr('r', new SVG.Number(x))
+ : this.rx(x).ry(y == null ? x : y)
}
})
SVG.extend(SVG.Path, {
// Get path length
- length: function() {
+ length: function () {
return this.node.getTotalLength()
- }
+ },
// Get point at length
-, pointAt: function(length) {
+ pointAt: function (length) {
return new SVG.Point(this.node.getPointAtLength(length))
}
})
SVG.extend([SVG.Parent, SVG.Text, SVG.Tspan, SVG.FX], {
// Set font
- font: function(a, v) {
- if (typeof a == 'object') {
+ font: function (a, v) {
+ if (typeof a === 'object') {
for (v in a) this.font(v, a[v])
}
- return a == 'leading' ?
- this.leading(v) :
- a == 'anchor' ?
- this.attr('text-anchor', v) :
- a == 'size' || a == 'family' || a == 'weight' || a == 'stretch' || a == 'variant' || a == 'style' ?
- this.attr('font-'+ a, v) :
- this.attr(a, v)
+ return a === 'leading'
+ ? this.leading(v)
+ : a === 'anchor'
+ ? this.attr('text-anchor', v)
+ : a === 'size' || a === 'family' || a === 'weight' || a === 'stretch' || a === 'variant' || a === 'style'
+ ? this.attr('font-' + a, v)
+ : this.attr(a, v)
}
})
diff --git a/src/svg.js b/src/svg.js
index ea27c5c..e6903da 100644
--- a/src/svg.js
+++ b/src/svg.js
@@ -1,100 +1,99 @@
+/* global createElement, capitalize */
+/* eslint-disable new-cap */
+
// The main wrapping element
-var SVG = this.SVG = function(element) {
+var SVG = this.SVG = function (element) {
if (SVG.supported) {
element = createElement(element)
-
return element
}
}
+// Svg must be supported if we reached this stage
+SVG.supported = true
+
// Default namespaces
-SVG.ns = 'http://www.w3.org/2000/svg'
+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.svgjs = 'http://svgjs.com/svgjs'
-// Svg support test
-SVG.supported = (function() {
- return !! document.createElementNS &&
- !! document.createElementNS(SVG.ns,'svg').createSVGRect
-})()
-
-// Don't bother to continue if SVG is not supported
-if (!SVG.supported) return false
-
// Element id sequence
-SVG.did = 1000
+SVG.did = 1000
// Get next named element id
-SVG.eid = function(name) {
+SVG.eid = function (name) {
return 'Svgjs' + capitalize(name) + (SVG.did++)
}
// Method for element creation
-SVG.create = function(name) {
+SVG.create = function (name) {
// create element
return document.createElementNS(this.ns, name)
}
// Method for extending objects
-SVG.extend = function(modules, methods) {
+SVG.extend = function (modules, methods) {
var key, i
modules = Array.isArray(modules) ? modules : [modules]
- for (i = modules.length - 1; i >= 0; i--)
- if (modules[i])
- for (key in methods)
+ for (i = modules.length - 1; i >= 0; i--) {
+ if (modules[i]) {
+ for (key in methods) {
modules[i].prototype[key] = methods[key]
+ }
+ }
+ }
}
// Invent new element
-SVG.invent = function(config) {
+SVG.invent = function (config) {
// Create element initializer
- var initializer = typeof config.create == 'function' ?
- config.create :
- function(node) {
- this.constructor.call(this, node || SVG.create(config.create))
+ var initializer = typeof config.create === 'function' ? config.create
+ : function (node) {
+ this.constructor(node || SVG.create(config.create))
}
// Inherit prototype
- if (config.inherit)
- initializer.prototype = new config.inherit
+ if (config.inherit) {
+ initializer.prototype = new config.inherit()
+ }
// Extend with methods
- if (config.extend)
+ if (config.extend) {
SVG.extend(initializer, config.extend)
+ }
// Attach construct method to parent
- if (config.construct)
- SVG.extend(config.parent || SVG.Container, config.construct)
+ if (config.construct) { SVG.extend(config.parent || SVG.Container, config.construct) }
return initializer
}
// Adopt existing svg elements
-SVG.adopt = function(node) {
+SVG.adopt = function (node) {
// check for presence of node
if (!node) return null
// make sure a node isn't already adopted
if (node.instance) return node.instance
- if(!(node instanceof window.SVGElement))
+ if (!(node instanceof window.SVGElement)) {
return new SVG.HtmlNode(node)
-
+ }
+
// initialize variables
var element
// adopt with element-specific settings
- if (node.nodeName == 'svg')
+ if (node.nodeName === 'svg') {
element = node.parentNode instanceof window.SVGElement ? new SVG.Nested(node) : new SVG.Doc(node)
- else if (node.nodeName == 'linearGradient' || node.nodeName == 'radialGradient')
+ } else if (node.nodeName === 'linearGradient' || node.nodeName === 'radialGradient') {
element = new SVG.Gradient(node)
- else if (SVG[capitalize(node.nodeName)])
+ } else if (SVG[capitalize(node.nodeName)]) {
element = new SVG[capitalize(node.nodeName)](node)
- else
- element = new SVG.Parent(node)
+ } else { element = new SVG.Parent(node) }
return element
}
diff --git a/src/symbol.js b/src/symbol.js
index f9c83e9..ca67607 100644
--- a/src/symbol.js
+++ b/src/symbol.js
@@ -1,14 +1,15 @@
+
SVG.Symbol = SVG.invent({
// Initialize node
- create: 'symbol'
+ create: 'symbol',
// Inherit from
-, inherit: SVG.Container
+ inherit: SVG.Container,
-, construct: {
+ construct: {
// create symbol
- symbol: function() {
- return this.put(new SVG.Symbol)
+ symbol: function () {
+ return this.put(new SVG.Symbol())
}
}
})
diff --git a/src/text.js b/src/text.js
index bf37d60..4242547 100644
--- a/src/text.js
+++ b/src/text.js
@@ -1,65 +1,66 @@
SVG.Text = SVG.invent({
// Initialize node
- create: function(node) {
- this.constructor.call(this, node || SVG.create('text'))
-
+ create: function (node) {
+ this.constructor(node || SVG.create('text'))
this.dom.leading = new SVG.Number(1.3) // store leading value for rebuilding
this._rebuild = true // enable automatic updating of dy values
- this._build = false // disable build mode for adding multiple lines
+ this._build = false // disable build mode for adding multiple lines
// set default font
this.attr('font-family', SVG.defaults.attrs['font-family'])
- }
+ },
// Inherit from
-, inherit: SVG.Parent
+ inherit: SVG.Parent,
// Add class methods
-, extend: {
+ extend: {
// Move over x-axis
- x: function(x) {
+ x: function (x) {
// act as getter
- if (x == null)
+ if (x == null) {
return this.attr('x')
+ }
return this.attr('x', x)
- }
+ },
// Move over y-axis
- , y: function(y) {
+ y: function (y) {
var oy = this.attr('y')
- , o = typeof oy === 'number' ? oy - this.bbox().y : 0
+ var o = typeof oy === 'number' ? oy - this.bbox().y : 0
// act as getter
- if (y == null)
+ if (y == null) {
return typeof oy === 'number' ? oy - o : oy
+ }
return this.attr('y', typeof y === 'number' ? y + o : y)
- }
+ },
// Move center over x-axis
- , cx: function(x) {
+ cx: function (x) {
return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2)
- }
+ },
// Move center over y-axis
- , cy: function(y) {
+ cy: function (y) {
return y == null ? this.bbox().cy : this.y(y - this.bbox().height / 2)
- }
+ },
// Set the text content
- , text: function(text) {
+ text: function (text) {
// act as getter
- if (text === undefined){
- var text = ''
- , children = this.node.childNodes
- , firstLine = 0
+ if (text === undefined) {
+ var children = this.node.childNodes
+ var firstLine = 0
+ text = ''
- for(var i = 0, len = children.length; i < len; ++i){
+ for (var i = 0, len = children.length; i < len; ++i) {
// skip textPaths - they are no lines
- if(children[i].nodeName == 'textPath') {
- if(i == 0) firstLine = 1
+ if (children[i].nodeName === 'textPath') {
+ if (i === 0) firstLine = 1
continue
}
// add newline if its not the first child and newLined is set to true
- if(i != firstLine && children[i].nodeType != 3 && SVG.adopt(children[i]).dom.newLined == true){
+ if (i !== firstLine && children[i].nodeType !== 3 && SVG.adopt(children[i]).dom.newLined === true) {
text += '\n'
}
@@ -76,53 +77,55 @@ SVG.Text = SVG.invent({
if (typeof text === 'function') {
// call block
text.call(this, this)
-
} else {
// store text and make sure text is not blank
text = text.split('\n')
// build new lines
- for (var i = 0, il = text.length; i < il; i++)
- this.tspan(text[i]).newLine()
+ for (var j = 0, jl = text.length; j < jl; j++) {
+ this.tspan(text[j]).newLine()
+ }
}
// disable build mode and rebuild lines
return this.build(false).rebuild()
- }
+ },
// Set font size
- , size: function(size) {
+ size: function (size) {
return this.attr('font-size', size).rebuild()
- }
+ },
// Set / get leading
- , leading: function(value) {
+ leading: function (value) {
// act as getter
- if (value == null)
+ if (value == null) {
return this.dom.leading
+ }
// act as setter
this.dom.leading = new SVG.Number(value)
return this.rebuild()
- }
+ },
// Rebuild appearance type
- , rebuild: function(rebuild) {
+ rebuild: function (rebuild) {
// store new rebuild flag if given
- if (typeof rebuild == 'boolean')
+ if (typeof rebuild === 'boolean') {
this._rebuild = rebuild
+ }
// define position of all lines
if (this._rebuild) {
var self = this
- , blankLineOffset = 0
- , dy = this.dom.leading * new SVG.Number(this.attr('font-size'))
+ var blankLineOffset = 0
+ var dy = this.dom.leading * new SVG.Number(this.attr('font-size'))
- this.each(function() {
+ this.each(function () {
if (this.dom.newLined) {
this.attr('x', self.attr('x'))
- if(this.text() == '\n') {
+ if (this.text() === '\n') {
blankLineOffset += dy
- }else{
+ } else {
this.attr('dy', dy + blankLineOffset)
blankLineOffset = 0
}
@@ -133,29 +136,29 @@ SVG.Text = SVG.invent({
}
return this
- }
+ },
// Enable / disable build mode
- , build: function(build) {
+ build: function (build) {
this._build = !!build
return this
- }
+ },
// overwrite method from parent to set data properly
- , setData: function(o){
+ setData: function (o) {
this.dom = o
this.dom.leading = new SVG.Number(o.leading || 1.3)
return this
}
- }
+ },
// Add parent method
-, construct: {
+ construct: {
// Create text element
- text: function(text) {
- return this.put(new SVG.Text).text(text)
- }
+ text: function (text) {
+ return this.put(new SVG.Text()).text(text)
+ },
// Create plain text element
- , plain: function(text) {
- return this.put(new SVG.Text).plain(text)
+ plain: function (text) {
+ return this.put(new SVG.Text()).plain(text)
}
}
@@ -163,31 +166,31 @@ SVG.Text = SVG.invent({
SVG.Tspan = SVG.invent({
// Initialize node
- create: 'tspan'
+ create: 'tspan',
// Inherit from
-, inherit: SVG.Parent
+ inherit: SVG.Parent,
// Add class methods
-, extend: {
+ extend: {
// Set text content
- text: function(text) {
- if(text == null) return this.node.textContent + (this.dom.newLined ? '\n' : '')
+ text: function (text) {
+ if (text == null) return this.node.textContent + (this.dom.newLined ? '\n' : '')
typeof text === 'function' ? text.call(this, this) : this.plain(text)
return this
- }
+ },
// Shortcut dx
- , dx: function(dx) {
+ dx: function (dx) {
return this.attr('dx', dx)
- }
+ },
// Shortcut dy
- , dy: function(dy) {
+ dy: function (dy) {
return this.attr('dy', dy)
- }
+ },
// Create new line
- , newLine: function() {
+ newLine: function () {
// fetch text parent
var t = this.parent(SVG.Text)
@@ -202,32 +205,34 @@ SVG.Tspan = SVG.invent({
SVG.extend([SVG.Text, SVG.Tspan], {
// Create plain text node
- plain: function(text) {
+ plain: function (text) {
// clear if build mode is disabled
- if (this._build === false)
+ if (this._build === false) {
this.clear()
+ }
// create text node
this.node.appendChild(document.createTextNode(text))
return this
- }
+ },
// Create a tspan
-, tspan: function(text) {
- var tspan = new SVG.Tspan
+ tspan: function (text) {
+ var tspan = new SVG.Tspan()
// clear if build mode is disabled
- if (!this._build)
+ if (!this._build) {
this.clear()
+ }
// add new tspan
this.node.appendChild(tspan.node)
return tspan.text(text)
- }
+ },
// FIXME: Does this also work for textpath?
// Get length of text element
-, length: function() {
+ length: function () {
return this.node.getComputedTextLength()
}
})
diff --git a/src/textpath.js b/src/textpath.js
index 2406e42..561f147 100644
--- a/src/textpath.js
+++ b/src/textpath.js
@@ -1,40 +1,40 @@
SVG.TextPath = SVG.invent({
// Initialize node
- create: 'textPath'
+ create: 'textPath',
// Inherit from
-, inherit: SVG.Text
+ inherit: SVG.Text,
// Define parent class
-, parent: SVG.Parent
+ parent: SVG.Parent,
// Add parent method
-, extend: {
- morphArray: SVG.PathArray
+ extend: {
+ MorphArray: SVG.PathArray,
// return the array of the path track element
- , array: function() {
+ array: function () {
var track = this.track()
return track ? track.array() : null
- }
+ },
// Plot path if any
- , plot: function(d) {
+ plot: function (d) {
var track = this.track()
- , pathArray = null
+ var pathArray = null
if (track) {
pathArray = track.plot(d)
}
return (d == null) ? pathArray : this
- }
+ },
// Get the path element
- , track: function() {
+ track: function () {
return this.reference('href')
}
- }
-, construct: {
- textPath: function(text, path) {
+ },
+ construct: {
+ textPath: function (text, path) {
return this.defs().path(path).text(text).addTo(this)
}
}
@@ -42,11 +42,11 @@ SVG.TextPath = SVG.invent({
SVG.extend([SVG.Text], {
// Create path for text to run on
- path: function(track) {
- var path = new SVG.TextPath
+ path: function (track) {
+ var path = new SVG.TextPath()
// if d is a path, reuse it
- if(!(track instanceof SVG.Path)) {
+ if (!(track instanceof SVG.Path)) {
// create path element
track = this.doc().defs().path(track)
}
@@ -56,18 +56,18 @@ SVG.extend([SVG.Text], {
// add textPath element as child node and return textPath
return this.put(path)
- }
+ },
// Todo: make this plural?
// Get the textPath children
- , textPath: function() {
+ textPath: function () {
return this.select('textPath')
}
})
SVG.extend([SVG.Path], {
// creates a textPath from this path
- text: function(text) {
- if(text instanceof SVG.Text) {
+ text: function (text) {
+ if (text instanceof SVG.Text) {
var txt = text.text()
return text.clear().path(this).text(txt)
}
diff --git a/src/transform.js b/src/transform.js
index 1175b13..4076301 100644
--- a/src/transform.js
+++ b/src/transform.js
@@ -1,3 +1,4 @@
+/* global ensureCentre, capitalize, arrayToMatrix */
SVG.extend(SVG.Element, {
@@ -40,6 +41,61 @@ SVG.extend(SVG.Element, {
// Get the resulting matrix and apply it to the element
var result = new SVG.Matrix().form(o)
, matrixString = result.toString()
+ // get current matrix
+ matrix = new SVG.Matrix(target)
+
+ // ensure relative flag
+ relative = !!relative || !!o.relative
+
+ // act on matrix
+ if (o.a != null) {
+ matrix = relative
+ ? matrix.multiply(new SVG.Matrix(o))
+ : new SVG.Matrix(o)
+
+ // act on rotation
+ } else if (o.rotation != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // apply transformation
+ matrix = relative
+ ? matrix.rotate(o.rotation, o.cx, o.cy)
+ : matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy)
+
+ // act on scale
+ } else if (o.scale != null || o.scaleX != null || o.scaleY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure scale values on both axes
+ o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
+ o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
+
+ if (!relative) {
+ // absolute; multiply inversed values
+ var e = matrix.extract()
+ o.scaleX = o.scaleX * 1 / e.scaleX
+ o.scaleY = o.scaleY * 1 / e.scaleY
+ }
+
+ matrix = matrix.scale(o.scaleX, o.scaleY, o.cx, o.cy)
+
+ // act on skew
+ } else if (o.skew != null || o.skewX != null || o.skewY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure skew values on both axes
+ o.skewX = o.skew != null ? o.skew : o.skewX != null ? o.skewX : 0
+ o.skewY = o.skew != null ? o.skew : o.skewY != null ? o.skewY : 0
+
+ if (!relative) {
+ // absolute; reset skew values
+ var el = matrix.extract()
+ matrix = matrix.multiply(new SVG.Matrix().skew(el.skewX, el.skewY, el.cx, el.cy).inverse())
+ }
+>>>>>>> 3.0.0
// Apply the result
return this.attr('transform', matrix)
@@ -147,36 +203,80 @@ SVG.extend(SVG.FX, {
//
// return this._callStart()
// }
+ // ensure scale values on both axes
+ o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
+ o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
+
+ matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy)
+
+ // act on skew
+ } else if (o.skewX != null || o.skewY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure skew values on both axes
+ o.skewX = o.skewX != null ? o.skewX : 0
+ o.skewY = o.skewY != null ? o.skewY : 0
+
+ matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy)
+
+ // act on flip
+ } else if (o.flip) {
+ if (o.flip === 'x' || o.flip === 'y') {
+ o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset
+ } else {
+ if (o.offset == null) {
+ bbox = target.bbox()
+ o.flip = bbox.cx
+ o.offset = bbox.cy
+ } else {
+ o.flip = o.offset
+ }
+ }
+
+ matrix = new SVG.Matrix().flip(o.flip, o.offset)
+
+ // act on translate
+ } else if (o.x != null || o.y != null) {
+ matrix = new SVG.Translate(o.x, o.y)
+ }
+
+ if (!matrix) return this
+
+ matrix.relative = relative
+
+ this.last().transforms.push(matrix)
+
+ return this._callStart()
+ }
+>>>>>>> 3.0.0
})
SVG.extend(SVG.Element, {
// Reset all transformations
- untransform: function() {
+ untransform: function () {
return this.attr('transform', null)
},
// merge the whole transformation chain into one matrix and returns it
- matrixify: function() {
-
+ matrixify: function () {
var matrix = (this.attr('transform') || '')
// split transformations
- .split(SVG.regex.transforms).slice(0,-1).map(function(str){
+ .split(SVG.regex.transforms).slice(0, -1).map(function (str) {
// generate key => value pairs
var kv = str.trim().split('(')
- return [kv[0], kv[1].split(SVG.regex.delimiter).map(function(str){ return parseFloat(str) })]
+ return [kv[0], kv[1].split(SVG.regex.delimiter).map(function (str) { return parseFloat(str) })]
})
// merge every transformation into one matrix
- .reduce(function(matrix, transform){
-
- if(transform[0] == 'matrix') return matrix.multiply(arrayToMatrix(transform[1]))
+ .reduce(function (matrix, transform) {
+ if (transform[0] === 'matrix') return matrix.multiply(arrayToMatrix(transform[1]))
return matrix[transform[0]].apply(matrix, transform[1])
-
}, new SVG.Matrix())
return matrix
},
// add an element to another parent without changing the visual representation on the screen
- toParent: function(parent) {
- if(this == parent) return this
+ toParent: function (parent) {
+ if (this === parent) return this
var ctm = this.screenCTM()
var pCtm = parent.screenCTM().inverse()
@@ -185,7 +285,7 @@ SVG.extend(SVG.Element, {
return this
},
// same as above with parent equals root-svg
- toDoc: function() {
+ toDoc: function () {
return this.toParent(this.doc())
}
})
@@ -332,3 +432,137 @@ SVG.extend(SVG.Element, {
// }
//
// })
+SVG.Transformation = SVG.invent({
+
+ create: function (source, inversed) {
+ if (arguments.length > 1 && typeof inversed !== 'boolean') {
+ return this.constructor.bind(this)([].slice.call(arguments))
+ }
+
+ var i, len
+ if (Array.isArray(source)) {
+ for (i = 0, len = this.arguments.length; i < len; ++i) {
+ this[this.arguments[i]] = source[i]
+ }
+ } else if (typeof source === 'object') {
+ for (i = 0, len = this.arguments.length; i < len; ++i) {
+ this[this.arguments[i]] = source[this.arguments[i]]
+ }
+ }
+
+ this.inversed = false
+
+ if (inversed === true) {
+ this.inversed = true
+ }
+ },
+
+ extend: {
+
+ arguments: [],
+ method: '',
+
+ at: function (pos) {
+ var params = []
+
+ for (var i = 0, len = this.arguments.length; i < len; ++i) {
+ params.push(this[this.arguments[i]])
+ }
+
+ var m = this._undo || new SVG.Matrix()
+
+ m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos)
+
+ return this.inversed ? m.inverse() : m
+ },
+
+ undo: function (o) {
+ for (var i = 0, len = this.arguments.length; i < len; ++i) {
+ o[this.arguments[i]] = typeof this[this.arguments[i]] === 'undefined' ? 0 : o[this.arguments[i]]
+ }
+
+ // The method SVG.Matrix.extract which was used before calling this
+ // method to obtain a value for the parameter o doesn't return a cx and
+ // a cy so we use the ones that were provided to this object at its creation
+ o.cx = this.cx
+ o.cy = this.cy
+
+ this._undo = new SVG[capitalize(this.method)](o, true).at(1)
+ return this
+ }
+
+ }
+
+})
+
+SVG.Translate = SVG.invent({
+
+ parent: SVG.Matrix,
+ inherit: SVG.Transformation,
+
+ create: function (source, inversed) {
+ this.constructor.apply(this, [].slice.call(arguments))
+ },
+
+ extend: {
+ arguments: ['transformedX', 'transformedY'],
+ method: 'translate'
+ }
+
+})
+
+SVG.Rotate = SVG.invent({
+
+ parent: SVG.Matrix,
+ inherit: SVG.Transformation,
+
+ create: function (source, inversed) {
+ this.constructor.apply(this, [].slice.call(arguments))
+ },
+
+ extend: {
+ arguments: ['rotation', 'cx', 'cy'],
+ method: 'rotate',
+ at: function (pos) {
+ var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy)
+ return this.inversed ? m.inverse() : m
+ },
+ undo: function (o) {
+ this._undo = o
+ return this
+ }
+ }
+
+})
+
+SVG.Scale = SVG.invent({
+
+ parent: SVG.Matrix,
+ inherit: SVG.Transformation,
+
+ create: function (source, inversed) {
+ this.constructor.apply(this, [].slice.call(arguments))
+ },
+
+ extend: {
+ arguments: ['scaleX', 'scaleY', 'cx', 'cy'],
+ method: 'scale'
+ }
+
+})
+
+SVG.Skew = SVG.invent({
+
+ parent: SVG.Matrix,
+ inherit: SVG.Transformation,
+
+ create: function (source, inversed) {
+ this.constructor.apply(this, [].slice.call(arguments))
+ },
+
+ extend: {
+ arguments: ['skewX', 'skewY', 'cx', 'cy'],
+ method: 'skew'
+ }
+})
+>>>>>>> 3.0.0
diff --git a/src/umd.js b/src/umd.js
index 55a9de0..bb8e300 100644
--- a/src/umd.js
+++ b/src/umd.js
@@ -1,3 +1,4 @@
+
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
@@ -11,6 +12,15 @@
}
}(typeof window !== "undefined" ? window : this, function(window, document) {
+// Check that our browser supports svg
+var supported = !! document.createElementNS &&
+ !! document.createElementNS('http://www.w3.org/2000/svg','svg').createSVGRect
+
+// If we don't support svg, just exit without doing anything
+if (!supported)
+ return {supported: false}
+
+// Otherwise, the library will be here
<%= contents %>
return SVG
diff --git a/src/use.js b/src/use.js
index 96f7411..2b8e65e 100644
--- a/src/use.js
+++ b/src/use.js
@@ -1,24 +1,25 @@
+
SVG.Use = SVG.invent({
// Initialize node
- create: 'use'
+ create: 'use',
// Inherit from
-, inherit: SVG.Shape
+ inherit: SVG.Shape,
// Add class methods
-, extend: {
+ extend: {
// Use element as a reference
- element: function(element, file) {
- // Set lined element
+ element: function (element, file) {
+ // Set lined element
return this.attr('href', (file || '') + '#' + element, SVG.xlink)
}
- }
-
+ },
+
// Add parent method
-, construct: {
+ construct: {
// Create a use element
- use: function(element, file) {
- return this.put(new SVG.Use).element(element, file)
+ use: function (element, file) {
+ return this.put(new SVG.Use()).element(element, file)
}
}
})
diff --git a/src/utilities.js b/src/utilities.js
index e44beac..5ebe808 100644
--- a/src/utilities.js
+++ b/src/utilities.js
@@ -1,41 +1,42 @@
SVG.utils = {
// Map function
- map: function(array, block) {
+ map: function (array, block) {
var i
- , il = array.length
- , result = []
+ var il = array.length
+ var result = []
- for (i = 0; i < il; i++)
+ for (i = 0; i < il; i++) {
result.push(block(array[i]))
+ }
return result
- }
+ },
// Filter function
-, filter: function(array, block) {
+ filter: function (array, block) {
var i
- , il = array.length
- , result = []
+ var il = array.length
+ var result = []
- for (i = 0; i < il; i++)
- if (block(array[i]))
- result.push(array[i])
+ for (i = 0; i < il; i++) {
+ if (block(array[i])) { result.push(array[i]) }
+ }
return result
- }
+ },
// Degrees to radians
-, radians: function(d) {
+ radians: function (d) {
return d % 360 * Math.PI / 180
- }
+ },
// Radians to degrees
-, degrees: function(r) {
+ degrees: function (r) {
return r * 180 / Math.PI % 360
- }
+ },
-, filterSVGElements: function(nodes) {
- return this.filter( nodes, function(el) { return el instanceof window.SVGElement })
+ filterSVGElements: function (nodes) {
+ return this.filter(nodes, function (el) { return el instanceof window.SVGElement })
}
}