From 15637375c5a00b64ae6b493187e5791cfadbc94f Mon Sep 17 00:00:00 2001 From: Saivan Date: Tue, 27 Feb 2018 01:14:06 +1100 Subject: [PATCH] All files now loosely abide by standard linting This commit completes the rest of the files, making sure they are in the standard linting format. Next we will add the linter to the build process of our application. --- dist/svg.js | 923 ++++++++++++++++++++++++---------------------- dist/svg.min.js | 4 +- src/parent.js | 68 ++-- src/parser.js | 15 +- src/path.js | 56 ++- src/patharray.js | 186 +++++----- src/pattern.js | 53 +-- src/point.js | 48 ++- src/pointarray.js | 85 +++-- src/pointed.js | 20 +- src/poly.js | 50 +-- src/rect.js | 13 +- src/regex.js | 38 +- src/selector.js | 14 +- src/shape.js | 7 +- src/sugar.js | 119 +++--- src/svg.js | 5 +- src/symbol.js | 11 +- src/text.js | 149 ++++---- src/textpath.js | 42 +-- src/transform.js | 159 ++++---- src/use.js | 20 +- src/utilities.js | 47 +-- 23 files changed, 1081 insertions(+), 1051 deletions(-) diff --git a/dist/svg.js b/dist/svg.js index 9639af2..05513c5 100644 --- a/dist/svg.js +++ b/dist/svg.js @@ -6,7 +6,7 @@ * @copyright Wout Fierens * @license MIT * -* BUILT: Tue Feb 27 2018 00:46:24 GMT+1100 (AEDT) +* BUILT: Tue Feb 27 2018 01:08:15 GMT+1100 (AEDT) */; (function(root, factory) { /* istanbul ignore next */ @@ -43,7 +43,8 @@ SVG.supported = (function() { })() // Don't bother to continue if SVG is not supported -if (!SVG.supported) return false +if (!SVG.supported) + return false // Element id sequence SVG.did = 1000 @@ -125,63 +126,63 @@ SVG.adopt = function(node) { // 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 } SVG.utils = { @@ -460,49 +461,55 @@ SVG.extend(SVG.Array, { } }) + // 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() @@ -510,7 +517,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 @@ -523,13 +530,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 @@ -537,83 +546,90 @@ 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} } }) 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]] @@ -622,19 +638,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) } @@ -642,21 +658,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() @@ -669,121 +685,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: @@ -791,74 +799,70 @@ 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 x = 0 + var y = 0 + 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() } @@ -2369,52 +2373,52 @@ SVG.Matrix = SVG.invent({ }) + 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() @@ -2423,21 +2427,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()) } }) @@ -2931,83 +2933,87 @@ SVG.extend(SVG.Element, { SVG.Parent = SVG.invent({ // Initialize node - create: function(node) { + create: function (node) { this.constructor.call(this, 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 @@ -3562,44 +3568,45 @@ SVG.Stop = SVG.invent({ 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) } } @@ -3607,17 +3614,18 @@ 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' }) } }) + SVG.Doc = SVG.invent({ // Initialize node create: function (node) { @@ -3673,14 +3681,15 @@ SVG.Doc = SVG.invent({ }) + SVG.Shape = SVG.invent({ // Initialize node - create: function(node) { + create: function (node) { this.constructor.call(this, node) - } + }, // Inherit from -, inherit: SVG.Element + inherit: SVG.Element }) @@ -3728,17 +3737,18 @@ SVG.extend(SVG.Parent, { } }) + 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()) } } }) @@ -3768,21 +3778,23 @@ SVG.Use = SVG.invent({ } }) + 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) } } }) + SVG.Circle = SVG.invent({ // Initialize node create: 'circle', @@ -3928,34 +3940,34 @@ SVG.Line = SVG.invent({ 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()) } } }) @@ -3963,118 +3975,119 @@ 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)) } - }) // 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) } }) + 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()) } } }) @@ -4139,66 +4152,68 @@ SVG.Image = SVG.invent({ SVG.Text = SVG.invent({ // Initialize node - create: function(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 + 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' } @@ -4215,53 +4230,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 } @@ -4272,29 +4289,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) } } @@ -4302,31 +4319,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) @@ -4341,32 +4358,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() } }) @@ -4589,119 +4608,122 @@ SVG.extend([SVG.Line, SVG.Polyline, SVG.Polygon, SVG.Path], { // 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(d, cx, cy) { + 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 }) - } + 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 }) - } + 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 }) - } + }, // Map matrix to transform -, matrix: function(m) { - return this.attr('transform', new SVG.Matrix(arguments.length == 6 ? [].slice.call(arguments) : m)) - } + matrix: function (m) { + return this.attr('transform', new SVG.Matrix(arguments.length === 6 ? [].slice.call(arguments) : m)) + }, // 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) } }) @@ -4770,31 +4792,31 @@ SVG.extend(SVG.Element, { }) // 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) } }) @@ -5153,10 +5175,11 @@ SVG.extend([SVG.Doc, SVG.Nested, SVG.Symbol, SVG.Image, SVG.Pattern, SVG.Marker, } }) -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) } @@ -5166,11 +5189,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/dist/svg.min.js b/dist/svg.min.js index 17a6fd2..d5d3603 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=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;n1?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=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=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&&eo);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.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 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":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){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,P.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,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||nthis.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=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=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;n0&&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=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 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={})}}),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 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=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;n1?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=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=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&&eo);return i},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.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 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":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){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,P.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,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||nthis.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=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=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;n0&&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){var e=this.node.childNodes,n=0;t="";for(var i=0,r=e.length;i=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 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={})}}),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 diff --git a/src/parent.js b/src/parent.js index f8b6ee1..4583ebf 100644 --- a/src/parent.js +++ b/src/parent.js @@ -1,82 +1,86 @@ SVG.Parent = SVG.invent({ // Initialize node - create: function(node) { + create: function (node) { this.constructor.call(this, 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..041027b 100644 --- a/src/path.js +++ b/src/path.js @@ -1,63 +1,61 @@ 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..d1b9420 100644 --- a/src/patharray.js +++ b/src/patharray.js @@ -1,49 +1,49 @@ 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 +52,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 +72,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 +99,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 +213,70 @@ 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 x = 0 + var y = 0 + 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..3941705 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..901b87b 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..db29797 100644 --- a/src/poly.js +++ b/src/poly.js @@ -1,33 +1,33 @@ 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 +35,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..8627521 100644 --- a/src/selector.js +++ b/src/selector.js @@ -1,29 +1,29 @@ // 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..fe2ac45 100644 --- a/src/shape.js +++ b/src/shape.js @@ -1,10 +1,11 @@ + SVG.Shape = SVG.invent({ // Initialize node - create: function(node) { + create: function (node) { this.constructor.call(this, node) - } + }, // Inherit from -, inherit: SVG.Element + inherit: SVG.Element }) diff --git a/src/sugar.js b/src/sugar.js index 117acea..c3a3332 100644 --- a/src/sugar.js +++ b/src/sugar.js @@ -1,117 +1,120 @@ // 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(d, cx, cy) { + 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 }) - } + 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 }) - } + 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 }) - } + }, // Map matrix to transform -, matrix: function(m) { - return this.attr('transform', new SVG.Matrix(arguments.length == 6 ? [].slice.call(arguments) : m)) - } + matrix: function (m) { + return this.attr('transform', new SVG.Matrix(arguments.length === 6 ? [].slice.call(arguments) : m)) + }, // 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..0f89439 100644 --- a/src/svg.js +++ b/src/svg.js @@ -20,7 +20,8 @@ SVG.supported = (function() { })() // Don't bother to continue if SVG is not supported -if (!SVG.supported) return false +if (!SVG.supported) + return false // Element id sequence SVG.did = 1000 @@ -82,7 +83,7 @@ SVG.adopt = function(node) { if(!(node instanceof window.SVGElement)) return new SVG.HtmlNode(node) - + // initialize variables var 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..486ec13 100644 --- a/src/text.js +++ b/src/text.js @@ -1,65 +1,66 @@ SVG.Text = SVG.invent({ // Initialize node - create: function(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 + 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..8362940 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 b738603..b6beb0d 100644 --- a/src/transform.js +++ b/src/transform.js @@ -1,9 +1,10 @@ + SVG.extend(SVG.Element, { // Add transformations - transform: function(o, relative) { + transform: function (o, relative) { // get target in case of the fx module, otherwise reference this var target = this - , matrix, bbox + var matrix, bbox // act as a getter if (typeof o !== 'object') { @@ -21,11 +22,9 @@ SVG.extend(SVG.Element, { // act on matrix if (o.a != null) { - matrix = relative ? - // relative - matrix.multiply(new SVG.Matrix(o)) : - // absolute - new SVG.Matrix(o) + matrix = relative + ? matrix.multiply(new SVG.Matrix(o)) + : new SVG.Matrix(o) // act on rotation } else if (o.rotation != null) { @@ -33,11 +32,9 @@ SVG.extend(SVG.Element, { 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) + 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) { @@ -76,10 +73,10 @@ SVG.extend(SVG.Element, { // act on flip } else if (o.flip) { - if(o.flip == 'x' || o.flip == 'y') { + if (o.flip === 'x' || o.flip === 'y') { o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset } else { - if(o.offset == null) { + if (o.offset == null) { bbox = target.bbox() o.flip = bbox.cx o.offset = bbox.cy @@ -107,16 +104,15 @@ SVG.extend(SVG.Element, { }) SVG.extend(SVG.FX, { - transform: function(o, relative) { + transform: function (o, relative) { // get target in case of the fx module, otherwise reference this var target = this.target() - , matrix, bbox + 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 } @@ -159,10 +155,10 @@ SVG.extend(SVG.FX, { // act on flip } else if (o.flip) { - if(o.flip == 'x' || o.flip == 'y') { + if (o.flip === 'x' || o.flip === 'y') { o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset } else { - if(o.offset == null) { + if (o.offset == null) { bbox = target.bbox() o.flip = bbox.cx o.offset = bbox.cy @@ -178,7 +174,7 @@ SVG.extend(SVG.FX, { matrix = new SVG.Translate(o.x, o.y) } - if(!matrix) return this + if (!matrix) return this matrix.relative = relative @@ -190,32 +186,29 @@ SVG.extend(SVG.FX, { 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() @@ -224,7 +217,7 @@ SVG.extend(SVG.Element, { return this }, // same as above with parent equals root-svg - toDoc: function() { + toDoc: function () { return this.toParent(this.doc()) } @@ -232,40 +225,37 @@ SVG.extend(SVG.Element, { SVG.Transformation = SVG.invent({ - create: function(source, inversed){ - - if(arguments.length > 1 && typeof inversed != 'boolean'){ + 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){ + 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){ + } 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){ + if (inversed === true) { this.inversed = true } + }, - } - -, extend: { - - arguments: [] - , method: '' + extend: { - , at: function(pos){ + arguments: [], + method: '', + at: function (pos) { var params = [] - for(var i = 0, len = this.arguments.length; i < len; ++i){ + for (var i = 0, len = this.arguments.length; i < len; ++i) { params.push(this[this.arguments[i]]) } @@ -274,12 +264,11 @@ SVG.Transformation = SVG.invent({ 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]] + 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 @@ -289,7 +278,6 @@ SVG.Transformation = SVG.invent({ o.cy = this.cy this._undo = new SVG[capitalize(this.method)](o, true).at(1) - return this } @@ -299,37 +287,37 @@ SVG.Transformation = SVG.invent({ SVG.Translate = SVG.invent({ - parent: SVG.Matrix -, inherit: SVG.Transformation + parent: SVG.Matrix, + inherit: SVG.Transformation, -, create: function(source, inversed){ + create: function (source, inversed) { this.constructor.apply(this, [].slice.call(arguments)) - } + }, -, extend: { - arguments: ['transformedX', 'transformedY'] - , method: 'translate' + extend: { + arguments: ['transformedX', 'transformedY'], + method: 'translate' } }) SVG.Rotate = SVG.invent({ - parent: SVG.Matrix -, inherit: SVG.Transformation + parent: SVG.Matrix, + inherit: SVG.Transformation, -, create: function(source, inversed){ + create: function (source, inversed) { this.constructor.apply(this, [].slice.call(arguments)) - } + }, -, extend: { - arguments: ['rotation', 'cx', 'cy'] - , method: 'rotate' - , at: function(pos){ + 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){ + }, + undo: function (o) { this._undo = o return this } @@ -339,32 +327,31 @@ SVG.Rotate = SVG.invent({ SVG.Scale = SVG.invent({ - parent: SVG.Matrix -, inherit: SVG.Transformation + parent: SVG.Matrix, + inherit: SVG.Transformation, -, create: function(source, inversed){ + create: function (source, inversed) { this.constructor.apply(this, [].slice.call(arguments)) - } + }, -, extend: { - arguments: ['scaleX', 'scaleY', 'cx', 'cy'] - , method: 'scale' + extend: { + arguments: ['scaleX', 'scaleY', 'cx', 'cy'], + method: 'scale' } }) SVG.Skew = SVG.invent({ - parent: SVG.Matrix -, inherit: SVG.Transformation + parent: SVG.Matrix, + inherit: SVG.Transformation, -, create: function(source, inversed){ + create: function (source, inversed) { this.constructor.apply(this, [].slice.call(arguments)) - } + }, -, extend: { - arguments: ['skewX', 'skewY', 'cx', 'cy'] - , method: 'skew' + extend: { + arguments: ['skewX', 'skewY', 'cx', 'cy'], + method: 'skew' } - }) diff --git a/src/use.js b/src/use.js index 96f7411..02bee12 100644 --- a/src/use.js +++ b/src/use.js @@ -1,24 +1,24 @@ 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 c41e8e4..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 = [] - - for (i = 0; i < il; 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) { + filter: function (array, block) { var i - , il = array.length - , result = [] - - for (i = 0; i < il; i++) - if (block(array[i])) - result.push(array[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) { + 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 }) } -} \ No newline at end of file +} -- 2.39.5