Comparing version 2.2.5 to 2.3.0
{ | ||
"name": "svg.js", | ||
"version":"2.2.5", | ||
"version":"2.3.0", | ||
"homepage": "http://svgjs.com/", | ||
@@ -5,0 +5,0 @@ "authors": [ |
@@ -5,3 +5,2 @@ # 3.0.0 | ||
- added `'random'` option and `randomize()` method to `SVG.Color` -> __TODO!__ | ||
- added `enqueue()` method to `SVG.FX` -> __TODO!__ | ||
- fixed a bug in clipping and masking where empty nodes persists after removal -> __TODO!__ | ||
@@ -12,2 +11,15 @@ - fixed a bug in IE11 with `mouseenter` and `mouseleave` -> __TODO!__ | ||
# 2.3.0 (30/03/2016) | ||
- added `SVG.Point` which serves as Wrapper to the native `SVGPoint` (#437) | ||
- added `element.point(x,y)` which transforms a point from screen coordinates to the elements space (#403) | ||
- fixed `svgjs:data` attribute which was not set properly in all browsers (#428) | ||
- fixed `isNumber` and `numberAndUnit` regex (#405) | ||
- fixed error where a parent node is not found when loading an image but the canvas was cleared (#447) | ||
- textpath now is a parent element, the lines method of text will return the tspans inside the textpath (#450) | ||
- fx module rewritten to support animation chaining and several other stuff (see docs) | ||
- fixed absolute transformation animations (not perfect but better) | ||
- fixed event listeners which didnt work correctly when identic funtions used | ||
- added `element.is()` which helps to check for the object instance faster (instanceof check) | ||
- added more fx specs | ||
# 2.2.5 (29/12/2015) | ||
@@ -14,0 +26,0 @@ - added check for existence of node (#431) |
@@ -5,3 +5,3 @@ { | ||
"description": "A lightweight library for manipulating and animating SVG", | ||
"version": "2.2.5", | ||
"version": "2.3.0", | ||
"keywords": ["svg"], | ||
@@ -8,0 +8,0 @@ "author": "Wout Fierens <wout@impinc.co.uk>", |
@@ -1,2 +0,2 @@ | ||
/*! svg.js v2.2.4 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,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)}function i(t){return t.toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()})}function r(t){return t.charAt(0).toUpperCase()+t.slice(1)}function s(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 o(t){var e=t.toString(16);return 1==e.length?"0"+e:e}function a(t,e,n){return null==n?n=t.height/t.width*e:null==e&&(e=t.width/t.height*n),{width:e,height:n}}function h(t,e,n){return{x:e*t.a+n*t.c+0,y:e*t.b+n*t.d+0}}function u(t){return{a:t[0],b:t[1],c:t[2],d:t[3],e:t[4],f:t[5]}}function l(t){return t instanceof y.Matrix||(t=new y.Matrix(t)),t}function c(t,e){t.cx=null==t.cx?e.bbox().cx:t.cx,t.cy=null==t.cy?e.bbox().cy:t.cy}function f(t){return t=t.replace(y.regex.whitespace,"").replace(y.regex.matrix,"").split(y.regex.matrixElements),u(y.utils.map(t,function(t){return parseFloat(t)}))}function d(t,e){return"number"==typeof t.from?t.from+(t.to-t.from)*e:t instanceof y.Color||t instanceof y.Number||t instanceof y.Matrix?t.at(e):1>e?t.from:t.to}function p(t){for(var e=0,n=t.length,i="";n>e;e++)i+=t[e][0],null!=t[e][1]&&(i+=t[e][1],null!=t[e][2]&&(i+=" ",i+=t[e][2],null!=t[e][3]&&(i+=" ",i+=t[e][3],i+=" ",i+=t[e][4],null!=t[e][5]&&(i+=" ",i+=t[e][5],i+=" ",i+=t[e][6],null!=t[e][7]&&(i+=" ",i+=t[e][7])))));return i+" "}function m(t){for(var e=t.childNodes.length-1;e>=0;e--)t.childNodes[e]instanceof SVGElement&&m(t.childNodes[e]);return y.adopt(t).id(y.eid(t.nodeName))}function x(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 g(t){var e=t.toString().match(y.regex.reference);return e?e[1]:void 0}var y=this.SVG=function(t){return y.supported?(t=new y.Doc(t),y.parser||y.prepare(t),t):void 0};if(y.ns="http://www.w3.org/2000/svg",y.xmlns="http://www.w3.org/2000/xmlns/",y.xlink="http://www.w3.org/1999/xlink",y.svgjs="http://svgjs.com/svgjs",y.supported=function(){return!!e.createElementNS&&!!e.createElementNS(y.ns,"svg").createSVGRect}(),!y.supported)return!1;y.did=1e3,y.eid=function(t){return"Svgjs"+r(t)+y.did++},y.create=function(t){var n=e.createElementNS(this.ns,t);return n.setAttribute("id",this.eid(t)),n},y.extend=function(){var t,e,n,i;for(t=[].slice.call(arguments),e=t.pop(),i=t.length-1;i>=0;i--)if(t[i])for(n in e)t[i].prototype[n]=e[n];y.Set&&y.Set.inherit&&y.Set.inherit()},y.invent=function(t){var e="function"==typeof t.create?t.create:function(){this.constructor.call(this,y.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&y.extend(e,t.extend),t.construct&&y.extend(t.parent||y.Container,t.construct),e},y.adopt=function(t){if(!t)return null;if(t.instance)return t.instance;var e;return e="svg"==t.nodeName?t.parentNode instanceof SVGElement?new y.Nested:new y.Doc:"linearGradient"==t.nodeName?new y.Gradient("linear"):"radialGradient"==t.nodeName?new y.Gradient("radial"):y[r(t.nodeName)]?new(y[r(t.nodeName)]):new y.Element(t),e.type=t.nodeName,e.node=t,t.instance=e,e instanceof y.Doc&&e.namespace().defs(),e.setData(JSON.parse(t.getAttribute("svgjs:data"))||{}),e},y.prepare=function(t){var n=e.getElementsByTagName("body")[0],i=(n?new y.Doc(n):t.nested()).size(2,0),r=y.create("path");i.node.appendChild(r),y.parser={body:n||t.parent(),draw:i.style("opacity:0;position:fixed;left:100%;top:100%;overflow:hidden"),poly:i.polyline().node,path:r}},y.regex={unit:/^(-?[\d\.]+)([a-z%]{0,2})$/,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,reference:/#([a-z0-9\-_]+)/i,matrix:/matrix\(|\)/g,matrixElements:/,*\s+|,/,whitespace:/\s/g,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^-?[\d\.]+$/,isPercent:/^-?[\d\.]+%$/,isImage:/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,negExp:/e\-/gi,comma:/,/g,hyphen:/\-/g,pathLetters:/[MLHVCSQTAZ]/gi,isPathLetter:/[MLHVCSQTAZ]/i,whitespaces:/\s+/,X:/X/g},y.utils={map:function(t,e){var n,i=t.length,r=[];for(n=0;i>n;n++)r.push(e(t[n]));return r},radians:function(t){return t%360*Math.PI/180},degrees:function(t){return 180*t/Math.PI%360},filterSVGElements:function(t){return[].filter.call(t,function(t){return t instanceof SVGElement})}},y.defaults={attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"}},y.Color=function(t){var e;this.r=0,this.g=0,this.b=0,"string"==typeof t?y.regex.isRgb.test(t)?(e=y.regex.rgb.exec(t.replace(/\s/g,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):y.regex.isHex.test(t)&&(e=y.regex.hex.exec(s(t)),this.r=parseInt(e[1],16),this.g=parseInt(e[2],16),this.b=parseInt(e[3],16)):"object"==typeof t&&(this.r=t.r,this.g=t.g,this.b=t.b)},y.extend(y.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+o(this.r)+o(this.g)+o(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},morph:function(t){return this.destination=new y.Color(t),this},at:function(t){return this.destination?(t=0>t?0:t>1?1:t,new y.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}}),y.Color.test=function(t){return t+="",y.regex.isHex.test(t)||y.regex.isRgb.test(t)},y.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},y.Color.isColor=function(t){return y.Color.isRgb(t)||y.Color.test(t)},y.Array=function(t,e){t=(t||[]).valueOf(),0==t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},y.extend(y.Array,{morph:function(t){if(this.destination=this.parse(t),this.value.length!=this.destination.length){for(var e=this.value[this.value.length-1],n=this.destination[this.destination.length-1];this.value.length>this.destination.length;)this.destination.push(n);for(;this.value.length<this.destination.length;)this.value.push(e)}return this},settle:function(){for(var t=0,e=this.value.length,n=[];e>t;t++)-1==n.indexOf(this.value[t])&&n.push(this.value[t]);return this.value=n},at:function(t){if(!this.destination)return this;for(var e=0,n=this.value.length,i=[];n>e;e++)i.push(this.value[e]+(this.destination[e]-this.value[e])*t);return new y.Array(i)},toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:this.split(t)},split:function(t){return t.trim().split(/\s+/)},reverse:function(){return this.value.reverse(),this}}),y.PointArray=function(t,e){this.constructor.call(this,t,e||[[0,0]])},y.PointArray.prototype=new y.Array,y.extend(y.PointArray,{toString:function(){for(var t=0,e=this.value.length,n=[];e>t;t++)n.push(this.value[t].join(","));return n.join(" ")},toLine:function(){return{x1:this.value[0][0],y1:this.value[0][1],x2:this.value[1][0],y2:this.value[1][1]}},at:function(t){if(!this.destination)return this;for(var e=0,n=this.value.length,i=[];n>e;e++)i.push([this.value[e][0]+(this.destination[e][0]-this.value[e][0])*t,this.value[e][1]+(this.destination[e][1]-this.value[e][1])*t]);return new y.PointArray(i)},parse:function(t){if(t=t.valueOf(),Array.isArray(t))return t;t=this.split(t);for(var e,n=0,i=t.length,r=[];i>n;n++)e=t[n].split(","),r.push([parseFloat(e[0]),parseFloat(e[1])]);return r},move:function(t,e){var n=this.bbox();if(t-=n.x,e-=n.y,!isNaN(t)&&!isNaN(e))for(var i=this.value.length-1;i>=0;i--)this.value[i]=[this.value[i][0]+t,this.value[i][1]+e];return this},size:function(t,e){var n,i=this.bbox();for(n=this.value.length-1;n>=0;n--)this.value[n][0]=(this.value[n][0]-i.x)*t/i.width+i.x,this.value[n][1]=(this.value[n][1]-i.y)*e/i.height+i.y;return this},bbox:function(){return y.parser.poly.setAttribute("points",this.toString()),y.parser.poly.getBBox()}}),y.PathArray=function(t,e){this.constructor.call(this,t,e||[["M",0,0]])},y.PathArray.prototype=new y.Array,y.extend(y.PathArray,{toString:function(){return p(this.value)},move:function(t,e){var n=this.bbox();if(t-=n.x,e-=n.y,!isNaN(t)&&!isNaN(e))for(var i,r=this.value.length-1;r>=0;r--)i=this.value[r][0],"M"==i||"L"==i||"T"==i?(this.value[r][1]+=t,this.value[r][2]+=e):"H"==i?this.value[r][1]+=t:"V"==i?this.value[r][1]+=e:"C"==i||"S"==i||"Q"==i?(this.value[r][1]+=t,this.value[r][2]+=e,this.value[r][3]+=t,this.value[r][4]+=e,"C"==i&&(this.value[r][5]+=t,this.value[r][6]+=e)):"A"==i&&(this.value[r][6]+=t,this.value[r][7]+=e);return this},size:function(t,e){var n,i,r=this.bbox();for(n=this.value.length-1;n>=0;n--)i=this.value[n][0],"M"==i||"L"==i||"T"==i?(this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x,this.value[n][2]=(this.value[n][2]-r.y)*e/r.height+r.y):"H"==i?this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x:"V"==i?this.value[n][1]=(this.value[n][1]-r.y)*e/r.height+r.y:"C"==i||"S"==i||"Q"==i?(this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x,this.value[n][2]=(this.value[n][2]-r.y)*e/r.height+r.y,this.value[n][3]=(this.value[n][3]-r.x)*t/r.width+r.x,this.value[n][4]=(this.value[n][4]-r.y)*e/r.height+r.y,"C"==i&&(this.value[n][5]=(this.value[n][5]-r.x)*t/r.width+r.x,this.value[n][6]=(this.value[n][6]-r.y)*e/r.height+r.y)):"A"==i&&(this.value[n][1]=this.value[n][1]*t/r.width,this.value[n][2]=this.value[n][2]*e/r.height,this.value[n][6]=(this.value[n][6]-r.x)*t/r.width+r.x,this.value[n][7]=(this.value[n][7]-r.y)*e/r.height+r.y);return this},parse:function(t){if(t instanceof y.PathArray)return t.valueOf();var e,n,i,r,s,o,a=0,h=0,u={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7};if("string"==typeof t){for(t=t.replace(y.regex.negExp,"X").replace(y.regex.pathLetters," $& ").replace(y.regex.hyphen," -").replace(y.regex.comma," ").replace(y.regex.X,"e-").trim().split(y.regex.whitespaces),e=t.length;--e;)if(t[e].indexOf(".")!=t[e].lastIndexOf(".")){var l=t[e].split("."),c=[l.shift(),l.shift()].join(".");t.splice.apply(t,[e,1].concat(c,l.map(function(t){return"."+t})))}}else t=t.reduce(function(t,e){return[].concat.apply(t,e)},[]);var o=[];do{for(y.regex.isPathLetter.test(t[0])?(r=t[0],t.shift()):"M"==r?r="L":"m"==r&&(r="l"),s=[r.toUpperCase()],e=0;e<u[s[0]];++e)s.push(parseFloat(t.shift()));r==s[0]?"M"==r||"L"==r||"C"==r||"Q"==r?(a=s[u[s[0]]-1],h=s[u[s[0]]]):"V"==r?h=s[1]:"H"==r?a=s[1]:"A"==r&&(a=s[6],h=s[7]):"m"==r||"l"==r||"c"==r||"s"==r||"q"==r||"t"==r?(s[1]+=a,s[2]+=h,null!=s[3]&&(s[3]+=a,s[4]+=h),null!=s[5]&&(s[5]+=a,s[6]+=h),a=s[u[s[0]]-1],h=s[u[s[0]]]):"v"==r?(s[1]+=h,h=s[1]):"h"==r?(s[1]+=a,a=s[1]):"a"==r&&(s[6]+=a,s[7]+=h,a=s[6],h=s[7]),"M"==s[0]&&(n=a,i=h),"Z"==s[0]&&(a=n,h=i),o.push(s)}while(t.length);return o},bbox:function(){return y.parser.path.setAttribute("d",this.toString()),y.parser.path.getBBox()}}),y.Number=y.invent({create:function(t,e){this.value=0,this.unit=e||"","number"==typeof t?this.value=isNaN(t)?0:isFinite(t)?t:0>t?-3.4e38:3.4e38:"string"==typeof t?(e=t.match(y.regex.unit),e&&(this.value=parseFloat(e[1]),"%"==e[2]?this.value/=100:"s"==e[2]&&(this.value*=1e3),this.unit=e[2])):t instanceof y.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},valueOf:function(){return this.value},plus:function(t){return new y.Number(this+new y.Number(t),this.unit)},minus:function(t){return this.plus(-new y.Number(t))},times:function(t){return new y.Number(this*new y.Number(t),this.unit)},divide:function(t){return new y.Number(this/new y.Number(t),this.unit)},to:function(t){var e=new y.Number(this);return"string"==typeof t&&(e.unit=t),e},morph:function(t){return this.destination=new y.Number(t),this},at:function(t){return this.destination?new y.Number(this.destination).minus(this).times(t).plus(this):this}}}),y.ViewBox=function(t){var e,n,i,r,s=1,o=1,a=t.bbox(),h=(t.attr("viewBox")||"").match(/-?[\d\.]+/g),u=t,l=t;for(i=new y.Number(t.width()),r=new y.Number(t.height());"%"==i.unit;)s*=i.value,i=new y.Number(u instanceof y.Doc?u.parent().offsetWidth:u.parent().width()),u=u.parent();for(;"%"==r.unit;)o*=r.value,r=new y.Number(l instanceof y.Doc?l.parent().offsetHeight:l.parent().height()),l=l.parent();this.x=a.x,this.y=a.y,this.width=i*s,this.height=r*o,this.zoom=1,h&&(e=parseFloat(h[0]),n=parseFloat(h[1]),i=parseFloat(h[2]),r=parseFloat(h[3]),this.zoom=this.width/this.height>i/r?this.height/r:this.width/i,this.x=e,this.y=n,this.width=i,this.height=r)},y.extend(y.ViewBox,{toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height}}),y.Element=y.invent({create:function(t){this._stroke=y.defaults.attrs.stroke,this.dom={},(this.node=t)&&(this.type=t.nodeName,this.node.instance=this,this._stroke=t.getAttribute("stroke")||this._stroke)},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=a(this.bbox(),t,e);return this.width(new y.Number(n.width)).height(new y.Number(n.height))},clone:function(){var t=m(this.node.cloneNode(!0));return this.after(t),t},remove:function(){return this.parent()&&this.parent().removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return t.put(this)},putIn:function(t){return t.add(this)},id:function(t){return this.attr("id",t)},inside:function(t,e){var n=this.bbox();return t>n.x&&e>n.y&&t<n.x+n.width&&e<n.y+n.height},show:function(){return this.style("display","")},hide:function(){return this.style("display","none")},visible:function(){return"none"!=this.style("display")},toString:function(){return this.attr("id")},classes:function(){var t=this.attr("class");return null==t?[]:t.trim().split(/\s+/)},hasClass:function(t){return-1!=this.classes().indexOf(t)},addClass:function(t){if(!this.hasClass(t)){var e=this.classes();e.push(t),this.attr("class",e.join(" "))}return this},removeClass:function(t){return this.hasClass(t)&&this.attr("class",this.classes().filter(function(e){return e!=t}).join(" ")),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t)},reference:function(t){return y.get(this.attr(t))},parent:function(t){var e=this;if(!e.node.parentNode)return null;if(e=y.adopt(e.node.parentNode),!t)return e;for(;e.node instanceof SVGElement;){if("string"==typeof t?e.matches(t):e instanceof t)return e;e=y.adopt(e.node.parentNode)}},doc:function(){return this instanceof y.Doc?this:this.parent(y.Doc)},parents:function(t){var e=[],n=this;do{if(n=n.parent(t),!n||!n.node)break;e.push(n)}while(n.parent);return e},matches:function(t){return n(this.node,t)},"native":function(){return this.node},svg:function(t){var n=e.createElement("svg");if(!(t&&this instanceof y.Parent))return n.appendChild(t=e.createElement("svg")),this.writeDataToDom(),t.appendChild(this.node.cloneNode(!0)),n.innerHTML.replace(/^<svg>/,"").replace(/<\/svg>$/,"");n.innerHTML="<svg>"+t.replace(/\n/,"").replace(/<(\w+)([^<]+?)\/>/g,"<$1$2></$1>")+"</svg>";for(var i=0,r=n.firstChild.childNodes.length;r>i;i++)this.node.appendChild(n.firstChild.firstChild);return this},writeDataToDom:function(){if(this.each||this.lines){var t=this.each?this:this.lines();t.each(function(){this.writeDataToDom()})}return this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttributeNS(y.svgjs,"svgjs:data",JSON.stringify(this.dom)),this},setData:function(t){return this.dom=t,this}}}),y.FX=y.invent({create:function(t){this.target=t},extend:{animate:function(t,e,n){var i,r,s,o=this.target,a=this;return"object"==typeof t&&(n=t.delay,e=t.ease,t=t.duration),t="="==t?t:null==t?1e3:new y.Number(t).valueOf(),e=e||"<>",a.at=function(t){var n;if(t=0>t?0:t>1?1:t,null==i){i=[];for(s in a.attrs)i.push(s);if(o.morphArray&&(a.destination.plot||i.indexOf("points")>-1)){var h,u=new o.morphArray(a.destination.plot||a.attrs.points||o.array());a.destination.size&&u.size(a.destination.size.width.to,a.destination.size.height.to),h=u.bbox(),a.destination.x?u.move(a.destination.x.to,h.y):a.destination.cx&&u.move(a.destination.cx.to-h.width/2,h.y),h=u.bbox(),a.destination.y?u.move(h.x,a.destination.y.to):a.destination.cy&&u.move(h.x,a.destination.cy.to-h.height/2),a.destination={plot:o.array().morph(u)}}}if(null==r){r=[];for(s in a.styles)r.push(s)}for(t="<>"==e?-Math.cos(t*Math.PI)/2+.5:">"==e?Math.sin(t*Math.PI/2):"<"==e?-Math.cos(t*Math.PI/2)+1:"-"==e?t:"function"==typeof e?e(t):t,a.destination.plot?o.plot(a.destination.plot.at(t)):(a.destination.x?o.x(a.destination.x.at(t)):a.destination.cx&&o.cx(a.destination.cx.at(t)),a.destination.y?o.y(a.destination.y.at(t)):a.destination.cy&&o.cy(a.destination.cy.at(t)),a.destination.size&&o.size(a.destination.size.width.at(t),a.destination.size.height.at(t))),a.destination.viewbox&&o.viewbox(a.destination.viewbox.x.at(t),a.destination.viewbox.y.at(t),a.destination.viewbox.width.at(t),a.destination.viewbox.height.at(t)),a.destination.leading&&o.leading(a.destination.leading.at(t)),n=i.length-1;n>=0;n--)o.attr(i[n],d(a.attrs[i[n]],t));for(n=r.length-1;n>=0;n--)o.style(r[n],d(a.styles[r[n]],t));a.situation.during&&a.situation.during.call(o,t,function(e,n){return d({from:e,to:n},t)})},"number"==typeof t&&(this.timeout=setTimeout(function(){var i=(new Date).getTime();a.situation.start=i,a.situation.play=!0,a.situation.finish=i+t,a.situation.duration=t,a.situation.ease=e,a.render=function(){if(a.situation.play===!0){var i=(new Date).getTime(),r=i>a.situation.finish?1:(i-a.situation.start)/t;a.situation.reversing&&(r=-r+1),a.at(r),i>a.situation.finish?(a.destination.plot&&o.plot(new y.PointArray(a.destination.plot.destination).settle()),a.situation.loop===!0||"number"==typeof a.situation.loop&&a.situation.loop>0?(a.situation.reverse&&(a.situation.reversing=!a.situation.reversing),"number"==typeof a.situation.loop&&((!a.situation.reverse||a.situation.reversing)&&--a.situation.loop,a.situation.reverse||1!=a.situation.loop||--a.situation.loop),a.animate(t,e,n)):a.situation.after?a.situation.after.apply(o,[a]):a.stop()):a.animationFrame=requestAnimationFrame(a.render)}else a.animationFrame=requestAnimationFrame(a.render)},a.render()},new y.Number(n).valueOf())),this},bbox:function(){return this.target.bbox()},attr:function(t,e){if("object"==typeof t)for(var n in t)this.attr(n,t[n]);else{var i=this.target.attr(t);"transform"==t?(this.attrs[t]&&(e=this.attrs[t].destination.multiply(e)),this.attrs[t]=new y.Matrix(this.target).morph(e),this.param&&(e=this.target.transform("rotation"),this.attrs[t].param={from:this.target.param||{rotation:e,cx:this.param.cx,cy:this.param.cy},to:this.param})):this.attrs[t]=y.Color.isColor(e)?new y.Color(i).morph(e):y.regex.unit.test(e)?new y.Number(i).morph(e):{from:i,to:e}}return this},style:function(t,e){if("object"==typeof t)for(var n in t)this.style(n,t[n]);else this.styles[t]={from:this.target.style(t),to:e};return this},x:function(t){return this.destination.x=new y.Number(this.target.x()).morph(t),this},y:function(t){return this.destination.y=new y.Number(this.target.y()).morph(t),this},cx:function(t){return this.destination.cx=new y.Number(this.target.cx()).morph(t),this},cy:function(t){return this.destination.cy=new y.Number(this.target.cy()).morph(t),this},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},size:function(t,e){if(this.target instanceof y.Text)this.attr("font-size",t);else{var n=this.target.bbox();this.destination.size={width:new y.Number(n.width).morph(t),height:new y.Number(n.height).morph(e)}}return this},plot:function(t){return this.destination.plot=t,this},leading:function(t){return this.target.destination.leading&&(this.destination.leading=new y.Number(this.target.destination.leading).morph(t)),this},viewbox:function(t,e,n,i){if(this.target instanceof y.Container){var r=this.target.viewbox();this.destination.viewbox={x:new y.Number(r.x).morph(t),y:new y.Number(r.y).morph(e),width:new y.Number(r.width).morph(n),height:new y.Number(r.height).morph(i)}}return this},update:function(t){return this.target instanceof y.Stop&&(null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new y.Number(t.offset))),this},during:function(t){return this.situation.during=t,this},after:function(t){return this.situation.after=t,this},loop:function(t,e){return this.situation.loop=this.situation.loops=t||!0,this.situation.reverse=!!e,this},stop:function(t){return t===!0?(this.animate(0),this.situation.after&&this.situation.after.apply(this.target,[this])):(clearTimeout(this.timeout),cancelAnimationFrame(this.animationFrame),this.attrs={},this.styles={},this.situation={},this.destination={}),this},pause:function(){return this.situation.play===!0&&(this.situation.play=!1,this.situation.pause=(new Date).getTime()),this},play:function(){if(this.situation.play===!1){var t=(new Date).getTime()-this.situation.pause;this.situation.finish+=t,this.situation.start+=t,this.situation.play=!0}return this}},parent:y.Element,construct:{animate:function(t,e,n){return(this.fx||(this.fx=new y.FX(this))).stop().animate(t,e,n)},stop:function(t){return this.fx&&this.fx.stop(t),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this}}}),y.BBox=y.invent({create:function(t){if(t){var e;try{e=t.node.getBBox()}catch(n){if(t instanceof y.Shape){var i=t.clone().addTo(y.parser.draw);e=i.bbox(),i.remove()}else e={x:t.node.clientLeft,y:t.node.clientTop,width:t.node.clientWidth,height:t.node.clientHeight}}this.x=e.x,this.y=e.y,this.width=e.width,this.height=e.height}x(this)},parent:y.Element,construct:{bbox:function(){return new y.BBox(this)}}}),y.TBox=y.invent({create:function(t){if(t){var e=t.ctm().extract(),n=t.bbox();this.width=n.width*e.scaleX,this.height=n.height*e.scaleY,this.x=n.x+e.x,this.y=n.y+e.y}x(this)},parent:y.Element,construct:{tbox:function(){return new y.TBox(this)}}}),y.RBox=y.invent({create:function(e){if(e){var n=e.doc().parent(),i=e.node.getBoundingClientRect(),r=1;for(this.x=i.left,this.y=i.top,this.x-=n.offsetLeft,this.y-=n.offsetTop;n=n.offsetParent;)this.x-=n.offsetLeft,this.y-=n.offsetTop;for(n=e;n.parent&&(n=n.parent());)n.viewbox&&(r*=n.viewbox().zoom,this.x-=n.x()||0,this.y-=n.y()||0);this.width=i.width/=r,this.height=i.height/=r}x(this),this.x+=t.pageXOffset,this.y+=t.pageYOffset},parent:y.Element,construct:{rbox:function(){return new y.RBox(this)}}}),[y.BBox,y.TBox,y.RBox].forEach(function(t){y.extend(t,{merge:function(e){var n=new t;return n.x=Math.min(this.x,e.x),n.y=Math.min(this.y,e.y),n.width=Math.max(this.x+this.width,e.x+e.width)-n.x,n.height=Math.max(this.y+this.height,e.y+e.height)-n.y,x(n)}})}),y.Matrix=y.invent({create:function(t){var e,n=u([1,0,0,1,0,0]);for(t=t instanceof y.Element?t.matrixify():"string"==typeof t?f(t):6==arguments.length?u([].slice.call(arguments)):"object"==typeof t?t:n,e=b.length-1;e>=0;e--)this[b[e]]=t&&"number"==typeof t[b[e]]?t[b[e]]:n[b[e]]},extend:{extract:function(){var t=h(this,0,1),e=h(this,1,0),n=180/Math.PI*Math.atan2(t.y,t.x)-90;return{x:this.e,y:this.f,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}},clone:function(){return new y.Matrix(this)},morph:function(t){return this.destination=new y.Matrix(t),this},at:function(t){if(!this.destination)return this;var e=new y.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});if(this.param&&this.param.to){var n={rotation:this.param.from.rotation+(this.param.to.rotation-this.param.from.rotation)*t,cx:this.param.from.cx,cy:this.param.from.cy};e=e.rotate((this.param.to.rotation-2*this.param.from.rotation)*t,n.cx,n.cy),e.param=n}return e},multiply:function(t){return new y.Matrix(this.native().multiply(l(t).native()))},inverse:function(){return new y.Matrix(this.native().inverse())},translate:function(t,e){return new y.Matrix(this.native().translate(t||0,e||0))},scale:function(t,e,n,i){return(1==arguments.length||3==arguments.length)&&(e=t),3==arguments.length&&(i=n,n=e),this.around(n,i,new y.Matrix(t,0,0,e,0,0))},rotate:function(t,e,n){return t=y.utils.radians(t),this.around(e,n,new y.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):this.scale(1,-1,0,e)},skew:function(t,e,n,i){return this.around(n,i,this.native().skewX(t||0).skewY(e||0))},skewX:function(t,e,n){return this.around(e,n,this.native().skewX(t||0))},skewY:function(t,e,n){return this.around(e,n,this.native().skewY(t||0))},around:function(t,e,n){return this.multiply(new y.Matrix(1,0,0,1,t||0,e||0)).multiply(n).multiply(new y.Matrix(1,0,0,1,-t||0,-e||0))},"native":function(){for(var t=y.parser.draw.node.createSVGMatrix(),e=b.length-1;e>=0;e--)t[b[e]]=this[b[e]];return t},toString:function(){return"matrix("+this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f+")"}},parent:y.Element,construct:{ctm:function(){return new y.Matrix(this.node.getCTM())},screenCTM:function(){return new y.Matrix(this.node.getScreenCTM())}}}),y.extend(y.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]=y.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?y.defaults.attrs[t]:y.regex.isNumber.test(e)?parseFloat(e):e;"stroke-width"==t?this.attr("stroke",parseFloat(e)>0?this._stroke:null):"stroke"==t&&(this._stroke=e),("fill"==t||"stroke"==t)&&(y.regex.isImage.test(e)&&(e=this.doc().defs().image(e,0,0)),e instanceof y.Image&&(e=this.doc().defs().pattern(0,0,function(){this.add(e)}))),"number"==typeof e?e=new y.Number(e):y.Color.isColor(e)?e=new y.Color(e):Array.isArray(e)?e=new y.Array(e):e instanceof y.Matrix&&e.param&&(this.param=e.param),"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}}),y.extend(y.Element,y.FX,{transform:function(t,e){var n,i=this.target||this;if("object"!=typeof t)return n=new y.Matrix(i).extract(),"object"==typeof this.param&&(n.rotation=this.param.rotation,n.cx=this.param.cx,n.cy=this.param.cy),"string"==typeof t?n[t]:n;if(n=this instanceof y.FX&&this.attrs.transform?this.attrs.transform:new y.Matrix(i),e=!!e||!!t.relative,null!=t.a)n=e?n.multiply(new y.Matrix(t)):new y.Matrix(t);else if(null!=t.rotation)c(t,i),e&&(t.rotation+=this.param&&null!=this.param.rotation?this.param.rotation:n.extract().rotation),this.param=t,this instanceof y.Element&&(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(c(t,i),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 r=n.extract();t.scaleX=1*t.scaleX/r.scaleX,t.scaleY=1*t.scaleY/r.scaleY}n=n.scale(t.scaleX,t.scaleY,t.cx,t.cy)}else if(null!=t.skewX||null!=t.skewY){if(c(t,i),t.skewX=null!=t.skewX?t.skewX:0,t.skewY=null!=t.skewY?t.skewY:0,!e){var r=n.extract();n=n.multiply((new y.Matrix).skew(r.skewX,r.skewY,t.cx,t.cy).inverse())}n=n.skew(t.skewX,t.skewY,t.cx,t.cy)}else t.flip?n=n.flip(t.flip,null==t.offset?i.bbox()["c"+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(this instanceof y.Pattern?"patternTransform":this instanceof y.Gradient?"gradientTransform":"transform",n)}}),y.extend(y.Element,{untransform:function(){return this.attr("transform",null)},matrixify:function(){var t=(this.attr("transform")||"").split(/\)\s*/).slice(0,-1).map(function(t){var e=t.trim().split("(");return[e[0],e[1].split(y.regex.matrixElements).map(function(t){return parseFloat(t)})]}).reduce(function(t,e){return"matrix"==e[0]?t.multiply(u(e[1])):t[e[0]].apply(t,e[1])},new y.Matrix);return t},toParent:function(t){if(this==t)return this;var e=this.screenCTM(),n=t.rect(1,1),i=n.screenCTM().inverse();return n.remove(),this.addTo(t).untransform().transform(i.multiply(e)),this},toDoc:function(){return this.toParent(this.doc())}}),y.extend(y.Element,{style:function(t,e){if(0==arguments.length)return this.node.style.cssText||"";if(arguments.length<2)if("object"==typeof t)for(e in t)this.style(e,t[e]);else{if(!y.regex.isCss.test(t))return this.node.style[i(t)];t=t.split(";");for(var n=0;n<t.length;n++)e=t[n].split(":"),this.style(e[0].replace(/\s+/g,""),e[1])}else this.node.style[i(t)]=null===e||y.regex.isBlank.test(e)?"":e;return this}}),y.Parent=y.invent({create:function(t){this.constructor.call(this,t)},inherit:y.Element,extend:{children:function(){return y.utils.map(y.utils.filterSVGElements(this.node.childNodes),function(t){return y.adopt(t)})},add:function(t,e){return this.has(t)||(e=null==e?this.children().length:e,this.node.insertBefore(t.node,this.node.childNodes[e]||null)),this},put:function(t,e){return this.add(t,e),t},has:function(t){return this.index(t)>=0},index:function(t){return this.children().indexOf(t)},get:function(t){return this.children()[t]},first:function(){return this.children()[0]},last:function(){return this.children()[this.children().length-1]},each:function(t,e){var n,i,r=this.children();for(n=0,i=r.length;i>n;n++)r[n]instanceof y.Element&&t.apply(r[n],[n,r]),e&&r[n]instanceof y.Container&&r[n].each(t,e);return this},removeElement:function(t){return this.node.removeChild(t.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return delete this._defs,this},defs:function(){return this.doc().defs()}}}),y.extend(y.Parent,{ungroup:function(t,e){return 0===e||this instanceof y.Defs?this:(t=t||(this instanceof y.Doc?this:this.parent(y.Parent)),e=e||1/0,this.each(function(){return this instanceof y.Defs?this:this instanceof y.Parent?this.ungroup(t,e-1):this.toParent(t)}),this.node.firstChild||this.remove(),this)},flatten:function(t,e){return this.ungroup(t,e)}}),y.Container=y.invent({create:function(t){this.constructor.call(this,t)},inherit:y.Parent,extend:{viewbox:function(t){return 0==arguments.length?new y.ViewBox(this):(t=1==arguments.length?[t.x,t.y,t.width,t.height]:[].slice.call(arguments),this.attr("viewBox",t))}}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach(function(t){y.Element.prototype[t]=function(e){var n=this;return this.node["on"+t]="function"==typeof e?function(){return e.apply(n,arguments)}:null,this}}),y.listeners=[],y.handlerMap=[],y.on=function(t,e,n,i){var r=n.bind(i||t.instance||t),s=(y.handlerMap.indexOf(t)+1||y.handlerMap.push(t))-1,o=e.split(".")[0],a=e.split(".")[1]||"*"; | ||
y.listeners[s]=y.listeners[s]||{},y.listeners[s][o]=y.listeners[s][o]||{},y.listeners[s][o][a]=y.listeners[s][o][a]||{},y.listeners[s][o][a][n]=r,t.addEventListener(o,r,!1)},y.off=function(t,e,n){var i=y.handlerMap.indexOf(t),r=e&&e.split(".")[0],s=e&&e.split(".")[1];if(-1!=i)if(n)y.listeners[i][r]&&y.listeners[i][r][s||"*"]&&(t.removeEventListener(r,y.listeners[i][r][s||"*"][n],!1),delete y.listeners[i][r][s||"*"][n]);else if(s&&r){if(y.listeners[i][r]&&y.listeners[i][r][s]){for(n in y.listeners[i][r][s])y.off(t,[r,s].join("."),n);delete y.listeners[i][r][s]}}else if(s)for(e in y.listeners[i])for(namespace in y.listeners[i][e])s===namespace&&y.off(t,[e,s].join("."));else if(r){if(y.listeners[i][r]){for(namespace in y.listeners[i][r])y.off(t,[r,namespace].join("."));delete y.listeners[i][r]}}else{for(e in y.listeners[i])y.off(t,e);delete y.listeners[i]}},y.extend(y.Element,{on:function(t,e,n){return y.on(this.node,t,e,n),this},off:function(t,e){return y.off(this.node,t,e),this},fire:function(t,e){return t instanceof Event?this.node.dispatchEvent(t):this.node.dispatchEvent(new w(t,{detail:e})),this}}),y.Defs=y.invent({create:"defs",inherit:y.Container}),y.G=y.invent({create:"g",inherit:y.Container,extend:{x:function(t){return null==t?this.transform("x"):this.transform({x:t-this.x()},!0)},y:function(t){return null==t?this.transform("y"):this.transform({y:t-this.y()},!0)},cx:function(t){return null==t?this.tbox().cx:this.x(t-this.tbox().width/2)},cy:function(t){return null==t?this.tbox().cy:this.y(t-this.tbox().height/2)},gbox:function(){var t=this.bbox(),e=this.transform();return t.x+=e.x,t.x2+=e.x,t.cx+=e.x,t.y+=e.y,t.y2+=e.y,t.cy+=e.y,t}},construct:{group:function(){return this.put(new y.G)}}}),y.extend(y.Element,{siblings:function(){return this.parent().children()},position:function(){return this.parent().index(this)},next:function(){return this.siblings()[this.position()+1]},previous:function(){return this.siblings()[this.position()-1]},forward:function(){var t=this.position()+1,e=this.parent();return e.removeElement(this).add(this,t),e instanceof y.Doc&&e.node.appendChild(e.defs().node),this},backward:function(){var t=this.position();return t>0&&this.parent().removeElement(this).add(this,t-1),this},front:function(){var t=this.parent();return t.node.appendChild(this.node),t instanceof y.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}}),y.Mask=y.invent({create:function(){this.constructor.call(this,y.create("mask")),this.targets=[]},inherit:y.Container,extend:{remove:function(){for(var t=this.targets.length-1;t>=0;t--)this.targets[t]&&this.targets[t].unmask();return this.targets=[],this.parent().removeElement(this),this}},construct:{mask:function(){return this.defs().put(new y.Mask)}}}),y.extend(y.Element,{maskWith:function(t){return this.masker=t instanceof y.Mask?t:this.parent().mask().add(t),this.masker.targets.push(this),this.attr("mask",'url("#'+this.masker.attr("id")+'")')},unmask:function(){return delete this.masker,this.attr("mask",null)}}),y.ClipPath=y.invent({create:function(){this.constructor.call(this,y.create("clipPath")),this.targets=[]},inherit:y.Container,extend:{remove:function(){for(var t=this.targets.length-1;t>=0;t--)this.targets[t]&&this.targets[t].unclip();return this.targets=[],this.parent().removeElement(this),this}},construct:{clip:function(){return this.defs().put(new y.ClipPath)}}}),y.extend(y.Element,{clipWith:function(t){return this.clipper=t instanceof y.ClipPath?t:this.parent().clip().add(t),this.clipper.targets.push(this),this.attr("clip-path",'url("#'+this.clipper.attr("id")+'")')},unclip:function(){return delete this.clipper,this.attr("clip-path",null)}}),y.Gradient=y.invent({create:function(t){this.constructor.call(this,y.create(t+"Gradient")),this.type=t},inherit:y.Container,extend:{at:function(t,e,n){return this.put(new y.Stop).update(t,e,n)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},fill:function(){return"url(#"+this.id()+")"},toString:function(){return this.fill()},attr:function(t,e,n){return"transform"==t&&(t="gradientTransform"),y.Container.prototype.attr.call(this,t,e,n)}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),y.extend(y.Gradient,y.FX,{from:function(t,e){return"radial"==(this.target||this).type?this.attr({fx:new y.Number(t),fy:new y.Number(e)}):this.attr({x1:new y.Number(t),y1:new y.Number(e)})},to:function(t,e){return"radial"==(this.target||this).type?this.attr({cx:new y.Number(t),cy:new y.Number(e)}):this.attr({x2:new y.Number(t),y2:new y.Number(e)})}}),y.extend(y.Defs,{gradient:function(t,e){return this.put(new y.Gradient(t)).update(e)}}),y.Stop=y.invent({create:"stop",inherit:y.Element,extend:{update:function(t){return("number"==typeof t||t instanceof y.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 y.Number(t.offset)),this}}}),y.Pattern=y.invent({create:"pattern",inherit:y.Container,extend:{fill:function(){return"url(#"+this.id()+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.fill()},attr:function(t,e,n){return"transform"==t&&(t="patternTransform"),y.Container.prototype.attr.call(this,t,e,n)}},construct:{pattern:function(t,e,n){return this.defs().pattern(t,e,n)}}}),y.extend(y.Defs,{pattern:function(t,e,n){return this.put(new y.Pattern).update(n).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),y.Doc=y.invent({create:function(t){t&&(t="string"==typeof t?e.getElementById(t):t,"svg"==t.nodeName?this.constructor.call(this,t):(this.constructor.call(this,y.create("svg")),t.appendChild(this.node)),this.namespace().size("100%","100%").defs())},inherit:y.Container,extend:{namespace:function(){return this.attr({xmlns:y.ns,version:"1.1"}).attr("xmlns:xlink",y.xlink,y.xmlns).attr("xmlns:svgjs",y.svgjs,y.xmlns)},defs:function(){if(!this._defs){var t;this._defs=(t=this.node.getElementsByTagName("defs")[0])?y.adopt(t):new y.Defs,this.node.appendChild(this._defs.node)}return this._defs},parent:function(){return"#document"==this.node.parentNode.nodeName?null:this.node.parentNode},spof:function(){var t=this.node.getScreenCTM();return t&&this.style("left",-t.e%1+"px").style("top",-t.f%1+"px"),this},remove:function(){return this.parent()&&this.parent().removeChild(this.node),this}}}),y.Shape=y.invent({create:function(t){this.constructor.call(this,t)},inherit:y.Element}),y.Bare=y.invent({create:function(t,e){if(this.constructor.call(this,y.create(t)),e)for(var n in e.prototype)"function"==typeof e.prototype[n]&&(this[n]=e.prototype[n])},inherit:y.Element,extend:{words:function(t){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this.node.appendChild(e.createTextNode(t)),this}}}),y.extend(y.Parent,{element:function(t,e){return this.put(new y.Bare(t,e))},symbol:function(){return this.defs().element("symbol",y.Container)}}),y.Use=y.invent({create:"use",inherit:y.Shape,extend:{element:function(t,e){return this.attr("href",(e||"")+"#"+t,y.xlink)}},construct:{use:function(t,e){return this.put(new y.Use).element(t,e)}}}),y.Rect=y.invent({create:"rect",inherit:y.Shape,construct:{rect:function(t,e){return this.put(new y.Rect).size(t,e)}}}),y.Circle=y.invent({create:"circle",inherit:y.Shape,construct:{circle:function(t){return this.put(new y.Circle).rx(new y.Number(t).divide(2)).move(0,0)}}}),y.extend(y.Circle,y.FX,{rx:function(t){return this.attr("r",t)},ry:function(t){return this.rx(t)}}),y.Ellipse=y.invent({create:"ellipse",inherit:y.Shape,construct:{ellipse:function(t,e){return this.put(new y.Ellipse).size(t,e).move(0,0)}}}),y.extend(y.Ellipse,y.Rect,y.FX,{rx:function(t){return this.attr("rx",t)},ry:function(t){return this.attr("ry",t)}}),y.extend(y.Circle,y.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 y.Number(t).divide(2))},height:function(t){return null==t?2*this.ry():this.ry(new y.Number(t).divide(2))},size:function(t,e){var n=a(this.bbox(),t,e);return this.rx(new y.Number(n.width).divide(2)).ry(new y.Number(n.height).divide(2))}}),y.Line=y.invent({create:"line",inherit:y.Shape,extend:{array:function(){return new y.PointArray([[this.attr("x1"),this.attr("y1")],[this.attr("x2"),this.attr("y2")]])},plot:function(t,e,n,i){return t=4==arguments.length?{x1:t,y1:e,x2:n,y2:i}:new y.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=a(this.bbox(),t,e);return this.attr(this.array().size(n.width,n.height).toLine())}},construct:{line:function(t,e,n,i){return this.put(new y.Line).plot(t,e,n,i)}}}),y.Polyline=y.invent({create:"polyline",inherit:y.Shape,construct:{polyline:function(t){return this.put(new y.Polyline).plot(t)}}}),y.Polygon=y.invent({create:"polygon",inherit:y.Shape,construct:{polygon:function(t){return this.put(new y.Polygon).plot(t)}}}),y.extend(y.Polyline,y.Polygon,{array:function(){return this._array||(this._array=new y.PointArray(this.attr("points")))},plot:function(t){return this.attr("points",this._array=new y.PointArray(t))},move:function(t,e){return this.attr("points",this.array().move(t,e))},size:function(t,e){var n=a(this.bbox(),t,e);return this.attr("points",this.array().size(n.width,n.height))}}),y.extend(y.Line,y.Polyline,y.Polygon,{morphArray:y.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)}}),y.Path=y.invent({create:"path",inherit:y.Shape,extend:{morphArray:y.PathArray,array:function(){return this._array||(this._array=new y.PathArray(this.attr("d")))},plot:function(t){return this.attr("d",this._array=new y.PathArray(t))},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=a(this.bbox(),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 y.Path).plot(t)}}}),y.Image=y.invent({create:"image",inherit:y.Shape,extend:{load:function(t){if(!t)return this;var n=this,i=e.createElement("img");return i.onload=function(){var e=n.parent(y.Pattern);null!==e&&(0==n.width()&&0==n.height()&&n.size(i.width,i.height),e&&0==e.width()&&0==e.height()&&e.size(n.width(),n.height()),"function"==typeof n._loaded&&n._loaded.call(n,{width:i.width,height:i.height,ratio:i.width/i.height,url:t}))},this.attr("href",i.src=this.src=t,y.xlink)},loaded:function(t){return this._loaded=t,this}},construct:{image:function(t,e,n){return this.put(new y.Image).load(t).size(e||0,n||e||0)}}}),y.Text=y.invent({create:function(){this.constructor.call(this,y.create("text")),this.dom.leading=new y.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",y.defaults.attrs["font-family"])},inherit:y.Shape,extend:{clone:function(){var t=m(this.node.cloneNode(!0));return this.after(t),t},x:function(t){return null==t?this.attr("x"):(this.textPath||this.lines().each(function(){this.dom.newLined&&this.x(t)}),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("undefined"==typeof t){for(var t="",e=this.node.childNodes,n=0,i=e.length;i>n;++n)0!=n&&3!=e[n].nodeType&&1==y.adopt(e[n]).dom.newLined&&(t+="\n"),t+=e[n].textContent;return t}if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{t=t.split("\n");for(var n=0,r=t.length;r>n;n++)this.tspan(t[n]).newLine()}return this.build(!1).rebuild()},size:function(t){return this.attr("font-size",t).rebuild()},leading:function(t){return null==t?this.dom.leading:(this.dom.leading=new y.Number(t),this.rebuild())},lines:function(){var t=y.utils.map(y.utils.filterSVGElements(this.node.childNodes),function(t){return y.adopt(t)});return new y.Set(t)},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this,n=0,i=this.dom.leading*new y.Number(this.attr("font-size"));this.lines().each(function(){this.dom.newLined&&(this.textPath||this.attr("x",e.attr("x")),"\n"==this.text()?n+=i:(this.attr("dy",i+n),n=0))}),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this},setData:function(t){return this.dom=t,this.dom.leading=t.leading?new y.Number(t.leading.value,t.leading.unit):new y.Number(1.3),this}},construct:{text:function(t){return this.put(new y.Text).text(t)},plain:function(t){return this.put(new y.Text).plain(t)}}}),y.Tspan=y.invent({create:"tspan",inherit:y.Shape,extend:{text:function(t){return null==t?this.node.textContent+(this.dom.newLined?"\n":""):("function"==typeof t?t.call(this,this):this.plain(t),this)},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.parent(y.Text);return this.dom.newLined=!0,this.dy(t.dom.leading*t.attr("font-size")).attr("x",t.x())}}}),y.extend(y.Text,y.Tspan,{plain:function(t){return this._build===!1&&this.clear(),this.node.appendChild(e.createTextNode(t)),this},tspan:function(t){var e=(this.textPath&&this.textPath()||this).node,n=new y.Tspan;return this._build===!1&&this.clear(),e.appendChild(n.node),n.text(t)},clear:function(){for(var t=(this.textPath&&this.textPath()||this).node;t.hasChildNodes();)t.removeChild(t.lastChild);return this},length:function(){return this.node.getComputedTextLength()}}),y.TextPath=y.invent({create:"textPath",inherit:y.Element,parent:y.Text,construct:{path:function(t){for(var e=new y.TextPath,n=this.doc().defs().path(t);this.node.hasChildNodes();)e.node.appendChild(this.node.firstChild);return this.node.appendChild(e.node),e.attr("href","#"+n,y.xlink),this},plot:function(t){var e=this.track();return e&&e.plot(t),this},track:function(){var t=this.textPath();return t?t.reference("href"):void 0},textPath:function(){return this.node.firstChild&&"textPath"==this.node.firstChild.nodeName?y.adopt(this.node.firstChild):void 0}}}),y.Nested=y.invent({create:function(){this.constructor.call(this,y.create("svg")),this.style("overflow","visible")},inherit:y.Container,construct:{nested:function(){return this.put(new y.Nested)}}}),y.A=y.invent({create:"a",inherit:y.Container,extend:{to:function(t){return this.attr("href",t,y.xlink)},show:function(t){return this.attr("show",t,y.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new y.A).to(t)}}}),y.extend(y.Element,{linkTo:function(t){var e=new y.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent().put(e).put(this)}}),y.Marker=y.invent({create:"marker",inherit:y.Container,extend:{width:function(t){return this.attr("markerWidth",t)},height:function(t){return this.attr("markerHeight",t)},ref:function(t,e){return this.attr("refX",t).attr("refY",e)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return"url(#"+this.id()+")"}},construct:{marker:function(t,e,n){return this.defs().marker(t,e,n)}}}),y.extend(y.Defs,{marker:function(t,e,n){return this.put(new y.Marker).size(t,e).ref(t/2,e/2).viewbox(0,0,t,e).attr("orient","auto").update(n)}}),y.extend(y.Line,y.Polyline,y.Polygon,y.Path,{marker:function(t,e,n,i){var r=["marker"];return"all"!=t&&r.push(t),r=r.join("-"),t=arguments[1]instanceof y.Marker?arguments[1]:this.doc().marker(e,n,i),this.attr(r,t)}});var v={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(t,e){return"color"==e?t:t+"-"+e}};["fill","stroke"].forEach(function(t){var e,n={};n[t]=function(n){if("string"==typeof n||y.Color.isRgb(n)||n&&"function"==typeof n.fill)this.attr(t,n);else for(e=v[t].length-1;e>=0;e--)null!=n[v[t][e]]&&this.attr(v.prefix(t,v[t][e]),n[v[t][e]]);return this},y.extend(y.Element,y.FX,n)}),y.extend(y.Element,y.FX,{rotate:function(t,e,n){return this.transform({rotation:t,cx:e,cy:n})},skew:function(t,e,n,i){return 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 this.transform({flip:t,offset:e})},matrix:function(t){return this.attr("transform",new y.Matrix(t))},opacity:function(t){return this.attr("opacity",t)},dx:function(t){return this.x((this.target||this).x()+t)},dy:function(t){return this.y((this.target||this).y()+t)},dmove:function(t,e){return this.dx(t).dy(e)}}),y.extend(y.Rect,y.Ellipse,y.Circle,y.Gradient,y.FX,{radius:function(t,e){var n=(this.target||this).type;return"radial"==n||"circle"==n?this.attr({r:new y.Number(t)}):this.rx(t).ry(null==e?t:e)}}),y.extend(y.Path,{length:function(){return this.node.getTotalLength()},pointAt:function(t){return this.node.getPointAtLength(t)}}),y.extend(y.Parent,y.Text,y.FX,{font:function(t){for(var e in t)"leading"==e?this.leading(t[e]):"anchor"==e?this.attr("text-anchor",t[e]):"size"==e||"family"==e||"weight"==e||"stretch"==e||"variant"==e||"style"==e?this.attr("font-"+e,t[e]):this.attr(e,t[e]);return this}}),y.Set=y.invent({create:function(t){Array.isArray(t)?this.members=t:this.clear()},extend:{add:function(){var t,e,n=[].slice.call(arguments);for(t=0,e=n.length;e>t;t++)this.members.push(n[t]);return this},remove:function(t){var e=this.index(t);return e>-1&&this.members.splice(e,1),this},each:function(t){for(var e=0,n=this.members.length;n>e;e++)t.apply(this.members[e],[e,this.members]);return this},clear:function(){return this.members=[],this},length:function(){return this.members.length},has:function(t){return this.index(t)>=0},index:function(t){return this.members.indexOf(t)},get:function(t){return this.members[t]},first:function(){return this.get(0)},last:function(){return this.get(this.members.length-1)},valueOf:function(){return this.members},bbox:function(){var t=new y.BBox;if(0==this.members.length)return t;var e=this.members[0].rbox();return t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,this.each(function(){t=t.merge(this.rbox())}),t}},construct:{set:function(t){return new y.Set(t)}}}),y.FX.Set=y.invent({create:function(t){this.set=t}}),y.Set.inherit=function(){var t,e=[];for(var t in y.Shape.prototype)"function"==typeof y.Shape.prototype[t]&&"function"!=typeof y.Set.prototype[t]&&e.push(t);e.forEach(function(t){y.Set.prototype[t]=function(){for(var e=0,n=this.members.length;n>e;e++)this.members[e]&&"function"==typeof this.members[e][t]&&this.members[e][t].apply(this.members[e],arguments);return"animate"==t?this.fx||(this.fx=new y.FX.Set(this)):this}}),e=[];for(var t in y.FX.prototype)"function"==typeof y.FX.prototype[t]&&"function"!=typeof y.FX.Set.prototype[t]&&e.push(t);e.forEach(function(t){y.FX.Set.prototype[t]=function(){for(var e=0,n=this.set.members.length;n>e;e++)this.set.members[e].fx[t].apply(this.set.members[e].fx,arguments);return this}})},y.extend(y.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(i){return this.attr("data-"+t)}else this.attr("data-"+t,null===e?null:n===!0||"string"==typeof e||"number"==typeof e?e:JSON.stringify(e));return this}}),y.extend(y.Element,{remember:function(t,e){if("object"==typeof arguments[0])for(var e in t)this.remember(e,t[e]);else{if(1==arguments.length)return this.memory()[t];this.memory()[t]=e}return this},forget:function(){if(0==arguments.length)this._memory={};else for(var t=arguments.length-1;t>=0;t--)delete this.memory()[arguments[t]];return this},memory:function(){return this._memory||(this._memory={})}}),y.get=function(t){var n=e.getElementById(g(t)||t);return y.adopt(n)},y.select=function(t,n){return new y.Set(y.utils.map((n||e).querySelectorAll(t),function(t){return y.adopt(t)}))},y.extend(y.Parent,{select:function(t){return y.select(t,this.node)}});var b="abcdef".split("");if("function"!=typeof w){var w=function(t,n){n=n||{bubbles:!1,cancelable:!1,detail:void 0};var i=e.createEvent("CustomEvent");return i.initCustomEvent(t,n.bubbles,n.cancelable,n.detail),i};w.prototype=t.Event.prototype,t.CustomEvent=w}return function(e){for(var n=0,i=["moz","webkit"],r=0;r<i.length&&!t.requestAnimationFrame;++r)e.requestAnimationFrame=e[i[r]+"RequestAnimationFrame"],e.cancelAnimationFrame=e[i[r]+"CancelAnimationFrame"]||e[i[r]+"CancelRequestAnimationFrame"];e.requestAnimationFrame=e.requestAnimationFrame||function(t){var i=(new Date).getTime(),r=Math.max(0,16-(i-n)),s=e.setTimeout(function(){t(i+r)},r);return n=i+r,s},e.cancelAnimationFrame=e.cancelAnimationFrame||e.clearTimeout}(t),y}); | ||
/*! svg.js v2.3.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 i(t,e){return t instanceof e}function n(t,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)}function r(t){return t.toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()})}function s(t){return t.charAt(0).toUpperCase()+t.slice(1)}function a(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 o(t){var e=t.toString(16);return 1==e.length?"0"+e:e}function h(t,e,i){return null==i?i=t.height/t.width*e:null==e&&(e=t.width/t.height*i),{width:e,height:i}}function u(t,e,i){return{x:e*t.a+i*t.c+0,y:e*t.b+i*t.d+0}}function l(t){return{a:t[0],b:t[1],c:t[2],d:t[3],e:t[4],f:t[5]}}function c(t){return t instanceof v.Matrix||(t=new v.Matrix(t)),t}function f(t,e){t.cx=null==t.cx?e.bbox().cx:t.cx,t.cy=null==t.cy?e.bbox().cy:t.cy}function d(t){return t=t.replace(v.regex.whitespace,"").replace(v.regex.matrix,"").split(v.regex.matrixElements),l(v.utils.map(t,function(t){return parseFloat(t)}))}function p(t){for(var e=0,i=t.length,n="";i>e;e++)n+=t[e][0],null!=t[e][1]&&(n+=t[e][1],null!=t[e][2]&&(n+=" ",n+=t[e][2],null!=t[e][3]&&(n+=" ",n+=t[e][3],n+=" ",n+=t[e][4],null!=t[e][5]&&(n+=" ",n+=t[e][5],n+=" ",n+=t[e][6],null!=t[e][7]&&(n+=" ",n+=t[e][7])))));return n+" "}function m(t){for(var e=t.childNodes.length-1;e>=0;e--)t.childNodes[e]instanceof SVGElement&&m(t.childNodes[e]);return v.adopt(t).id(v.eid(t.nodeName))}function x(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 g(t){var e=t.toString().match(v.regex.reference);return e?e[1]:void 0}var v=this.SVG=function(t){return v.supported?(t=new v.Doc(t),v.parser||v.prepare(t),t):void 0};if(v.ns="http://www.w3.org/2000/svg",v.xmlns="http://www.w3.org/2000/xmlns/",v.xlink="http://www.w3.org/1999/xlink",v.svgjs="http://svgjs.com/svgjs",v.supported=function(){return!!e.createElementNS&&!!e.createElementNS(v.ns,"svg").createSVGRect}(),!v.supported)return!1;v.did=1e3,v.eid=function(t){return"Svgjs"+s(t)+v.did++},v.create=function(t){var i=e.createElementNS(this.ns,t);return i.setAttribute("id",this.eid(t)),i},v.extend=function(){var t,e,i,n;for(t=[].slice.call(arguments),e=t.pop(),n=t.length-1;n>=0;n--)if(t[n])for(i in e)t[n].prototype[i]=e[i];v.Set&&v.Set.inherit&&v.Set.inherit()},v.invent=function(t){var e="function"==typeof t.create?t.create:function(){this.constructor.call(this,v.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&v.extend(e,t.extend),t.construct&&v.extend(t.parent||v.Container,t.construct),e},v.adopt=function(t){if(!t)return null;if(t.instance)return t.instance;var e;return e="svg"==t.nodeName?t.parentNode instanceof SVGElement?new v.Nested:new v.Doc:"linearGradient"==t.nodeName?new v.Gradient("linear"):"radialGradient"==t.nodeName?new v.Gradient("radial"):v[s(t.nodeName)]?new(v[s(t.nodeName)]):new v.Element(t),e.type=t.nodeName,e.node=t,t.instance=e,e instanceof v.Doc&&e.namespace().defs(),e.setData(JSON.parse(t.getAttribute("svgjs:data"))||{}),e},v.prepare=function(t){var i=e.getElementsByTagName("body")[0],n=(i?new v.Doc(i):t.nested()).size(2,0),r=v.create("path");n.node.appendChild(r),v.parser={body:i||t.parent(),draw:n.style("opacity:0;position:fixed;left:100%;top:100%;overflow:hidden"),poly:n.polyline().node,path:r}},v.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,matrix:/matrix\(|\)/g,matrixElements:/,*\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,negExp:/e\-/gi,comma:/,/g,hyphen:/\-/g,pathLetters:/[MLHVCSQTAZ]/gi,isPathLetter:/[MLHVCSQTAZ]/i,whitespaces:/\s+/,X:/X/g},v.utils={map:function(t,e){var i,n=t.length,r=[];for(i=0;n>i;i++)r.push(e(t[i]));return r},radians:function(t){return t%360*Math.PI/180},degrees:function(t){return 180*t/Math.PI%360},filterSVGElements:function(t){return[].filter.call(t,function(t){return t instanceof SVGElement})}},v.defaults={attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"}},v.Color=function(t){var e;this.r=0,this.g=0,this.b=0,"string"==typeof t?v.regex.isRgb.test(t)?(e=v.regex.rgb.exec(t.replace(/\s/g,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):v.regex.isHex.test(t)&&(e=v.regex.hex.exec(a(t)),this.r=parseInt(e[1],16),this.g=parseInt(e[2],16),this.b=parseInt(e[3],16)):"object"==typeof t&&(this.r=t.r,this.g=t.g,this.b=t.b)},v.extend(v.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+o(this.r)+o(this.g)+o(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},morph:function(t){return this.destination=new v.Color(t),this},at:function(t){return this.destination?(t=0>t?0:t>1?1:t,new v.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}}),v.Color.test=function(t){return t+="",v.regex.isHex.test(t)||v.regex.isRgb.test(t)},v.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},v.Color.isColor=function(t){return v.Color.isRgb(t)||v.Color.test(t)},v.Array=function(t,e){t=(t||[]).valueOf(),0==t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},v.extend(v.Array,{morph:function(t){if(this.destination=this.parse(t),this.value.length!=this.destination.length){for(var e=this.value[this.value.length-1],i=this.destination[this.destination.length-1];this.value.length>this.destination.length;)this.destination.push(i);for(;this.value.length<this.destination.length;)this.value.push(e)}return this},settle:function(){for(var t=0,e=this.value.length,i=[];e>t;t++)-1==i.indexOf(this.value[t])&&i.push(this.value[t]);return this.value=i},at:function(t){if(!this.destination)return this;for(var e=0,i=this.value.length,n=[];i>e;e++)n.push(this.value[e]+(this.destination[e]-this.value[e])*t);return new v.Array(n)},toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:this.split(t)},split:function(t){return t.trim().split(/\s+/)},reverse:function(){return this.value.reverse(),this}}),v.PointArray=function(t,e){this.constructor.call(this,t,e||[[0,0]])},v.PointArray.prototype=new v.Array,v.extend(v.PointArray,{toString:function(){for(var t=0,e=this.value.length,i=[];e>t;t++)i.push(this.value[t].join(","));return i.join(" ")},toLine:function(){return{x1:this.value[0][0],y1:this.value[0][1],x2:this.value[1][0],y2:this.value[1][1]}},at:function(t){if(!this.destination)return this;for(var e=0,i=this.value.length,n=[];i>e;e++)n.push([this.value[e][0]+(this.destination[e][0]-this.value[e][0])*t,this.value[e][1]+(this.destination[e][1]-this.value[e][1])*t]);return new v.PointArray(n)},parse:function(t){if(t=t.valueOf(),Array.isArray(t))return t;t=this.split(t);for(var e,i=0,n=t.length,r=[];n>i;i++)e=t[i].split(","),r.push([parseFloat(e[0]),parseFloat(e[1])]);return r},move:function(t,e){var i=this.bbox();if(t-=i.x,e-=i.y,!isNaN(t)&&!isNaN(e))for(var n=this.value.length-1;n>=0;n--)this.value[n]=[this.value[n][0]+t,this.value[n][1]+e];return this},size:function(t,e){var i,n=this.bbox();for(i=this.value.length-1;i>=0;i--)this.value[i][0]=(this.value[i][0]-n.x)*t/n.width+n.x,this.value[i][1]=(this.value[i][1]-n.y)*e/n.height+n.y;return this},bbox:function(){return v.parser.poly.setAttribute("points",this.toString()),v.parser.poly.getBBox()}}),v.PathArray=function(t,e){this.constructor.call(this,t,e||[["M",0,0]])},v.PathArray.prototype=new v.Array,v.extend(v.PathArray,{toString:function(){return p(this.value)},move:function(t,e){var i=this.bbox();if(t-=i.x,e-=i.y,!isNaN(t)&&!isNaN(e))for(var n,r=this.value.length-1;r>=0;r--)n=this.value[r][0],"M"==n||"L"==n||"T"==n?(this.value[r][1]+=t,this.value[r][2]+=e):"H"==n?this.value[r][1]+=t:"V"==n?this.value[r][1]+=e:"C"==n||"S"==n||"Q"==n?(this.value[r][1]+=t,this.value[r][2]+=e,this.value[r][3]+=t,this.value[r][4]+=e,"C"==n&&(this.value[r][5]+=t,this.value[r][6]+=e)):"A"==n&&(this.value[r][6]+=t,this.value[r][7]+=e);return this},size:function(t,e){var i,n,r=this.bbox();for(i=this.value.length-1;i>=0;i--)n=this.value[i][0],"M"==n||"L"==n||"T"==n?(this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x,this.value[i][2]=(this.value[i][2]-r.y)*e/r.height+r.y):"H"==n?this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x:"V"==n?this.value[i][1]=(this.value[i][1]-r.y)*e/r.height+r.y:"C"==n||"S"==n||"Q"==n?(this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x,this.value[i][2]=(this.value[i][2]-r.y)*e/r.height+r.y,this.value[i][3]=(this.value[i][3]-r.x)*t/r.width+r.x,this.value[i][4]=(this.value[i][4]-r.y)*e/r.height+r.y,"C"==n&&(this.value[i][5]=(this.value[i][5]-r.x)*t/r.width+r.x,this.value[i][6]=(this.value[i][6]-r.y)*e/r.height+r.y)):"A"==n&&(this.value[i][1]=this.value[i][1]*t/r.width,this.value[i][2]=this.value[i][2]*e/r.height,this.value[i][6]=(this.value[i][6]-r.x)*t/r.width+r.x,this.value[i][7]=(this.value[i][7]-r.y)*e/r.height+r.y);return this},parse:function(t){if(t instanceof v.PathArray)return t.valueOf();var e,i,n,r,s,a,o=0,h=0,u={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7};if("string"==typeof t){for(t=t.replace(v.regex.negExp,"X").replace(v.regex.pathLetters," $& ").replace(v.regex.hyphen," -").replace(v.regex.comma," ").replace(v.regex.X,"e-").trim().split(v.regex.whitespaces),e=t.length;--e;)if(t[e].indexOf(".")!=t[e].lastIndexOf(".")){var l=t[e].split("."),c=[l.shift(),l.shift()].join(".");t.splice.apply(t,[e,1].concat(c,l.map(function(t){return"."+t})))}}else t=t.reduce(function(t,e){return[].concat.apply(t,e)},[]);var a=[];do{for(v.regex.isPathLetter.test(t[0])?(r=t[0],t.shift()):"M"==r?r="L":"m"==r&&(r="l"),s=[r.toUpperCase()],e=0;e<u[s[0]];++e)s.push(parseFloat(t.shift()));r==s[0]?"M"==r||"L"==r||"C"==r||"Q"==r?(o=s[u[s[0]]-1],h=s[u[s[0]]]):"V"==r?h=s[1]:"H"==r?o=s[1]:"A"==r&&(o=s[6],h=s[7]):"m"==r||"l"==r||"c"==r||"s"==r||"q"==r||"t"==r?(s[1]+=o,s[2]+=h,null!=s[3]&&(s[3]+=o,s[4]+=h),null!=s[5]&&(s[5]+=o,s[6]+=h),o=s[u[s[0]]-1],h=s[u[s[0]]]):"v"==r?(s[1]+=h,h=s[1]):"h"==r?(s[1]+=o,o=s[1]):"a"==r&&(s[6]+=o,s[7]+=h,o=s[6],h=s[7]),"M"==s[0]&&(i=o,n=h),"Z"==s[0]&&(o=i,h=n),a.push(s)}while(t.length);return a},bbox:function(){return v.parser.path.setAttribute("d",this.toString()),v.parser.path.getBBox()}}),v.Number=v.invent({create:function(t,e){this.value=0,this.unit=e||"","number"==typeof t?this.value=isNaN(t)?0:isFinite(t)?t:0>t?-3.4e38:3.4e38:"string"==typeof t?(e=t.match(v.regex.numberAndUnit),e&&(this.value=parseFloat(e[1]),"%"==e[5]?this.value/=100:"s"==e[5]&&(this.value*=1e3),this.unit=e[5])):t instanceof v.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 new v.Number(this+new v.Number(t),this.unit)},minus:function(t){return this.plus(-new v.Number(t))},times:function(t){return new v.Number(this*new v.Number(t),this.unit)},divide:function(t){return new v.Number(this/new v.Number(t),this.unit)},to:function(t){var e=new v.Number(this);return"string"==typeof t&&(e.unit=t),e},morph:function(t){return this.destination=new v.Number(t),this},at:function(t){return this.destination?new v.Number(this.destination).minus(this).times(t).plus(this):this}}}),v.ViewBox=v.invent({create:function(t){var e,i,n,r,s,a,o,h,u=[1,0,0,1],l=1,c=1,f=/-?[\d\.]+/g;if(t instanceof v.Element){for(o=t,h=t,a=(t.attr("viewBox")||"").match(f),s=t.bbox,n=new v.Number(t.width()),r=new v.Number(t.height());"%"==n.unit;)l*=n.value,n=new v.Number(o instanceof v.Doc?o.parent().offsetWidth:o.parent().width()),o=o.parent();for(;"%"==r.unit;)c*=r.value,r=new v.Number(h instanceof v.Doc?h.parent().offsetHeight:h.parent().height()),h=h.parent();this.x=0,this.y=0,this.width=n*l,this.height=r*c,this.zoom=1,a&&(e=parseFloat(a[0]),i=parseFloat(a[1]),n=parseFloat(a[2]),r=parseFloat(a[3]),this.zoom=this.width/this.height>n/r?this.height/r:this.width/n,this.x=e,this.y=i,this.width=n,this.height=r)}else t="string"==typeof t?t.match(f).map(function(t){return parseFloat(t)}):Array.isArray(t)?t:"object"==typeof t?[t.x,t.y,t.width,t.height]:4==arguments.length?[].slice.call(arguments):u,this.x=t[0],this.y=t[1],this.width=t[2],this.height=t[3]},extend:{toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height},morph:function(t){var t=1==arguments.length?[t.x,t.y,t.width,t.height]:[].slice.call(arguments);return this.destination=new v.ViewBox(t),this},at:function(t){return this.destination?new v.ViewBox([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}}}),v.Element=v.invent({create:function(t){this._stroke=v.defaults.attrs.stroke,this.dom={},(this.node=t)&&(this.type=t.nodeName,this.node.instance=this,this._stroke=t.getAttribute("stroke")||this._stroke)},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 i=h(this.bbox(),t,e);return this.width(new v.Number(i.width)).height(new v.Number(i.height))},clone:function(){var t=m(this.node.cloneNode(!0));return this.after(t),t},remove:function(){return this.parent()&&this.parent().removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return t.put(this)},putIn:function(t){return t.add(this)},id:function(t){return this.attr("id",t)},inside:function(t,e){var i=this.bbox();return t>i.x&&e>i.y&&t<i.x+i.width&&e<i.y+i.height},show:function(){return this.style("display","")},hide:function(){return this.style("display","none")},visible:function(){return"none"!=this.style("display")},toString:function(){return this.attr("id")},classes:function(){var t=this.attr("class");return null==t?[]:t.trim().split(/\s+/)},hasClass:function(t){return-1!=this.classes().indexOf(t)},addClass:function(t){if(!this.hasClass(t)){var e=this.classes();e.push(t),this.attr("class",e.join(" "))}return this},removeClass:function(t){return this.hasClass(t)&&this.attr("class",this.classes().filter(function(e){return e!=t}).join(" ")),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t)},reference:function(t){return v.get(this.attr(t))},parent:function(t){var e=this;if(!e.node.parentNode)return null;if(e=v.adopt(e.node.parentNode),!t)return e;for(;e&&e.node instanceof SVGElement;){if("string"==typeof t?e.matches(t):e instanceof t)return e;e=v.adopt(e.node.parentNode)}},doc:function(){return this instanceof v.Doc?this:this.parent(v.Doc)},parents:function(t){var e=[],i=this;do{if(i=i.parent(t),!i||!i.node)break;e.push(i)}while(i.parent);return e},matches:function(t){return n(this.node,t)},"native":function(){return this.node},svg:function(t){var i=e.createElement("svg");if(!(t&&this instanceof v.Parent))return i.appendChild(t=e.createElement("svg")),this.writeDataToDom(),t.appendChild(this.node.cloneNode(!0)),i.innerHTML.replace(/^<svg>/,"").replace(/<\/svg>$/,"");i.innerHTML="<svg>"+t.replace(/\n/,"").replace(/<(\w+)([^<]+?)\/>/g,"<$1$2></$1>")+"</svg>";for(var n=0,r=i.firstChild.childNodes.length;r>n;n++)this.node.appendChild(i.firstChild.firstChild);return this},writeDataToDom:function(){if(this.each||this.lines){var t=this.each?this:this.lines();t.each(function(){this.writeDataToDom()})}return this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttribute("svgjs:data",JSON.stringify(this.dom)),this},setData:function(t){return this.dom=t,this},is:function(t){return i(this,t)}}}),v.easing={"-":function(t){return t},"<>":function(t){return-Math.cos(t*Math.PI)/2+.5},">":function(t){return Math.sin(t*Math.PI/2)},"<":function(t){return-Math.cos(t*Math.PI/2)+1}},v.morph=function(t,e){return new MorphObj(t,e).at(pos)},v.Situation=v.invent({create:function(t){this.init=!1,this.reversed=!1,this.reversing=!1,this.duration=new v.Number(t.duration).valueOf(),this.delay=new v.Number(t.delay).valueOf(),this.start=+new Date+this.delay,this.finish=this.start+this.duration,this.ease=t.ease,this.loop=!1,this.loops=!1,this.animations={},this.attrs={},this.styles={},this.transforms=[],this.once={}}}),v.Delay=function(t){this.delay=new v.Number(t).valueOf()},v.FX=v.invent({create:function(t){this._target=t,this.situations=[],this.active=!1,this.situation=null,this.paused=!1,this.lastPos=0,this.pos=0},extend:{animate:function(t,e,i){"object"==typeof t&&(e=t.ease,i=t.delay,t=t.duration);var n=new v.Situation({duration:t||1e3,delay:i||0,ease:v.easing[e||"-"]||e});return this.queue(n),this},delay:function(t){var t=new v.Delay(t);return this.queue(t)},target:function(t){return t&&t instanceof v.Element?(this._target=t,this):this._target},timeToPos:function(t){return(t-this.situation.start)/this.situation.duration},posToTime:function(t){return this.situation.duration*t+this.situation.start},startAnimFrame:function(){this.stopAnimFrame(),this.animationFrame=requestAnimationFrame(function(){this.step()}.bind(this))},stopAnimFrame:function(){cancelAnimationFrame(this.animationFrame)},start:function(){return!this.active&&this.situation&&(this.situation.start=+new Date+this.situation.delay,this.situation.finish=this.situation.start+this.situation.duration,this.initAnimations(),this.active=!0,this.startAnimFrame()),this},queue:function(t){return("function"==typeof t||t instanceof v.Situation||t instanceof v.Delay)&&this.situations.push(t),this.situation||(this.situation=this.situations.shift()),this},dequeue:function(){if(this.situation&&this.situation.stop&&this.situation.stop(),this.situation=this.situations.shift(),this.situation){var t=function(){this.situation instanceof v.Situation?this.initAnimations().at(0):this.situation instanceof v.Delay?this.dequeue():this.situation.call(this)}.bind(this);this.situation.delay?setTimeout(function(){t()},this.situation.delay):t()}return this},initAnimations:function(){var t,e=this.situation;if(e.init)return this;for(t in e.animations)"viewbox"==t?e.animations[t]=this.target().viewbox().morph(e.animations[t]):(e.animations[t].value="plot"==t?this.target().array().value:this.target()[t](),e.animations[t].value.value&&(e.animations[t].value=e.animations[t].value.value),e.animations[t].relative&&(e.animations[t].destination.value=e.animations[t].destination.value+e.animations[t].value));for(t in e.attrs)if(e.attrs[t]instanceof v.Color){var i=new v.Color(this.target().attr(t));e.attrs[t].r=i.r,e.attrs[t].g=i.g,e.attrs[t].b=i.b}else e.attrs[t].value=this.target().attr(t);for(t in e.styles)e.styles[t].value=this.target().style(t);return e.initialTransformation=this.target().matrixify(),e.init=!0,this},clearQueue:function(){return this.situations=[],this},clearCurrent:function(){return this.situation=null,this},stop:function(t,e){return this.active||this.start(),e&&this.clearQueue(),this.active=!1,t&&(this.situation.loop=!1,this.situation.loops%2==0&&this.situation.reversing&&(this.situation.reversed=!0),this.at(1)),this.stopAnimFrame(),clearTimeout(this.timeout),this.clearCurrent()},reset:function(){if(this.situation){var t=this.situation;this.stop(),this.situation=t,this.at(0)}return this},finish:function(){for(this.stop(!0,!1);this.dequeue().situation&&this.stop(!0,!1););return this.clearQueue().clearCurrent(),this},at:function(t){return this.pos=t,this.situation.start=+new Date-t*this.situation.duration,this.situation.finish=this.situation.start+this.situation.duration,this.step(!0)},speed:function(t){return this.situation.duration=this.situation.duration*this.pos+(1-this.pos)*this.situation.duration/t,this.situation.finish=this.situation.start+this.situation.duration,this.at(this.pos)},loop:function(t,e){return this.situation.loop=this.situation.loops=t||!0,e&&(this.last().reversing=!0),this},pause:function(){return this.paused=!0,this.stopAnimFrame(),clearTimeout(this.timeout),this},play:function(){return this.paused?(this.paused=!1,this.at(this.pos)):this},reverse:function(t){var e=this.last();return e.reversed="undefined"==typeof t?!e.reversed:t,this},progress:function(t){return t?this.situation.ease(this.pos):this.pos},after:function(t){var e=this.last(),i=function n(i){i.detail.situation==e&&(t.call(this,e),this.off("finished.fx",n))};return this.target().on("finished.fx",i),this},during:function(t){var e=this.last(),i=function(i){i.detail.situation==e&&t.call(this,i.detail.pos,v.morph,i.detail.eased,e)};return this.target().off("during.fx",i).on("during.fx",i),this.after(function(){this.off("during.fx",i)})},afterAll:function(t){var e=function i(){t.call(this),this.off("allfinished.fx",i)};return this.target().off("allfinished.fx",e).on("allfinished.fx",e),this},duringAll:function(t){var e=function(e){t.call(this,e.detail.pos,v.morph,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)})},last:function(){return this.situations.length?this.situations[this.situations.length-1]:this.situation},add:function(t,e,i){return this.last()[i||"animations"][t]=e,setTimeout(function(){this.start()}.bind(this),0),this},step:function(t){if(t||(this.pos=this.timeToPos(+new Date)),this.pos>=1&&(this.situation.loop===!0||"number"==typeof this.situation.loop&&--this.situation.loop))return this.situation.reversing&&(this.situation.reversed=!this.situation.reversed),this.at(this.pos-1);this.situation.reversed&&(this.pos=1-this.pos),this.pos>1&&(this.pos=1),this.pos<0&&(this.pos=0);var e=this.situation.ease(this.pos);for(var i in this.situation.once)i>this.lastPos&&e>=i&&(this.situation.once[i].call(this.target(),this.pos,e),delete this.situation.once[i]);return this.active&&this.target().fire("during",{pos:this.pos,eased:e,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.target().off(".fx"),this.active=!1),this.active?this.dequeue():this.clearCurrent()):!this.paused&&this.active&&this.startAnimFrame(),this.lastPos=e,this):this},eachAt:function(){var t,e,i=this,n=this.target(),r=this.situation;for(t in r.animations)e=[].concat(r.animations[t]).map(function(t){return t.at?t.at(r.ease(i.pos),i.pos):t}),n[t].apply(n,e);for(t in r.attrs)e=[t].concat(r.attrs[t]).map(function(t){return t.at?t.at(r.ease(i.pos),i.pos):t}),n.attr.apply(n,e);for(t in r.styles)e=[t].concat(r.styles[t]).map(function(t){return t.at?t.at(r.ease(i.pos),i.pos):t}),n.style.apply(n,e);if(r.transforms.length){e=r.initialTransformation;for(t in r.transforms){var s=r.transforms[t];s instanceof v.Matrix?e=s.relative?e.multiply(s.at(r.ease(this.pos))):e.morph(s).at(r.ease(this.pos)):(s.relative||s.undo(e.extract()),e=e.multiply(s.at(r.ease(this.pos))))}n.matrix(e)}return this},once:function(t,e,i){return i||(t=this.situation.ease(t)),this.situation.once[t]=e,this}},parent:v.Element,construct:{animate:function(t,e,i){return(this.fx||(this.fx=new v.FX(this))).animate(t,e,i)},delay:function(t){return(this.fx||(this.fx=new v.FX(this))).delay(t)},stop:function(t,e){return this.fx&&this.fx.stop(t,e),this},finish:function(){return this.fx&&this.fx.finish(),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this}}}),v.MorphObj=v.invent({create:function(t,e){return v.Color.isColor(e)?new v.Color(t).morph(e):v.regex.numberAndUnit.test(e)?new v.Number(t).morph(e):(this.value=0,this.destination=e,void 0)},extend:{at:function(t,e){return 1>e?this.value:this.destination},valueOf:function(){return this.value}}}),v.extend(v.FX,{attr:function(t,e){if("object"==typeof t)for(var i in t)this.attr(i,t[i]);else this.add(t,new v.MorphObj(null,e),"attrs");return this},style:function(t,e){if("object"==typeof t)for(var i in t)this.style(i,t[i]);else this.add(t,new v.MorphObj(null,e),"styles");return this},x:function(t,e){if(this.target()instanceof v.G)return this.transform({x:t},e),this;var i=(new v.Number).morph(t);return i.relative=e,this.add("x",i)},y:function(t,e){if(this.target()instanceof v.G)return this.transform({y:t},e),this;var i=(new v.Number).morph(t);return i.relative=e,this.add("y",i)},cx:function(t){return this.add("cx",(new v.Number).morph(t))},cy:function(t){return this.add("cy",(new v.Number).morph(t))},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},size:function(t,e){if(this.target()instanceof v.Text)this.attr("font-size",t);else{var i;t&&e||(i=this.target().bbox()),t||(t=i.width/i.height*e),e||(e=i.height/i.width*t),this.add("width",(new v.Number).morph(t)).add("height",(new v.Number).morph(e))}return this},plot:function(t){return this.add("plot",this.target().array().morph(t))},leading:function(t){return this.target().leading?this.add("leading",(new v.Number).morph(t)):this},viewbox:function(t,e,i,n){return this.target()instanceof v.Container&&this.add("viewbox",new v.ViewBox(t,e,i,n)),this},update:function(t){if(this.target()instanceof v.Stop){if("number"==typeof t||t instanceof v.Number)return this.update({offset:arguments[0],color:arguments[1],opacity:arguments[2]});null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",t.offset)}return this}}),v.BBox=v.invent({create:function(t){if(t){var e;try{e=t.node.getBBox()}catch(i){if(t instanceof v.Shape){var n=t.clone().addTo(v.parser.draw);e=n.bbox(),n.remove()}else e={x:t.node.clientLeft,y:t.node.clientTop,width:t.node.clientWidth,height:t.node.clientHeight}}this.x=e.x,this.y=e.y,this.width=e.width,this.height=e.height}x(this)},parent:v.Element,construct:{bbox:function(){return new v.BBox(this)}}}),v.TBox=v.invent({create:function(t){if(t){var e=t.ctm().extract(),i=t.bbox();this.width=i.width*e.scaleX,this.height=i.height*e.scaleY,this.x=i.x+e.x,this.y=i.y+e.y}x(this)},parent:v.Element,construct:{tbox:function(){return new v.TBox(this)}}}),v.RBox=v.invent({create:function(e){if(e){var i=e.doc().parent(),n=e.node.getBoundingClientRect(),r=1;for(this.x=n.left,this.y=n.top,this.x-=i.offsetLeft,this.y-=i.offsetTop;i=i.offsetParent;)this.x-=i.offsetLeft,this.y-=i.offsetTop;for(i=e;i.parent&&(i=i.parent());)i.viewbox&&(r*=i.viewbox().zoom,this.x-=i.x()||0,this.y-=i.y()||0);this.width=n.width/=r,this.height=n.height/=r}x(this),this.x+=t.pageXOffset,this.y+=t.pageYOffset},parent:v.Element,construct:{rbox:function(){return new v.RBox(this)}}}),[v.BBox,v.TBox,v.RBox].forEach(function(t){v.extend(t,{merge:function(e){var i=new t;return i.x=Math.min(this.x,e.x),i.y=Math.min(this.y,e.y),i.width=Math.max(this.x+this.width,e.x+e.width)-i.x,i.height=Math.max(this.y+this.height,e.y+e.height)-i.y,x(i)}})}),v.Matrix=v.invent({create:function(t){var e,i=l([1,0,0,1,0,0]);for(t=t instanceof v.Element?t.matrixify():"string"==typeof t?d(t):6==arguments.length?l([].slice.call(arguments)):"object"==typeof t?t:i,e=w.length-1;e>=0;--e)this[w[e]]=t&&"number"==typeof t[w[e]]?t[w[e]]:i[w[e]]},extend:{extract:function(){var t=u(this,0,1),e=u(this,1,0),i=180/Math.PI*Math.atan2(t.y,t.x)-90;return{x:this.e,y:this.f,transformedX:(this.e*Math.cos(i*Math.PI/180)+this.f*Math.sin(i*Math.PI/180))/Math.sqrt(this.a*this.a+this.b*this.b),transformedY:(this.f*Math.cos(i*Math.PI/180)+this.e*Math.sin(-i*Math.PI/180))/Math.sqrt(this.c*this.c+this.d*this.d),skewX:-i,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:i,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f,matrix:new v.Matrix(this)}},clone:function(){return new v.Matrix(this)},morph:function(t){return this.destination=new v.Matrix(t),this},at:function(t){if(!this.destination)return this;var e=new v.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});if(this.param&&this.param.to){var i={rotation:this.param.from.rotation+(this.param.to.rotation-this.param.from.rotation)*t,cx:this.param.from.cx,cy:this.param.from.cy};e=e.rotate((this.param.to.rotation-2*this.param.from.rotation)*t,i.cx,i.cy),e.param=i}return e},multiply:function(t){return new v.Matrix(this.native().multiply(c(t).native()))},inverse:function(){return new v.Matrix(this.native().inverse())},translate:function(t,e){return new v.Matrix(this.native().translate(t||0,e||0))},scale:function(t,e,i,n){return(1==arguments.length||3==arguments.length)&&(e=t),3==arguments.length&&(n=i,i=e),this.around(i,n,new v.Matrix(t,0,0,e,0,0))},rotate:function(t,e,i){return t=v.utils.radians(t),this.around(e,i,new v.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):this.scale(1,-1,0,e)},skew:function(t,e,i,n){return this.around(i,n,this.native().skewX(t||0).skewY(e||0))},skewX:function(t,e,i){return this.around(e,i,this.native().skewX(t||0))},skewY:function(t,e,i){return this.around(e,i,this.native().skewY(t||0))},around:function(t,e,i){return this.multiply(new v.Matrix(1,0,0,1,t||0,e||0)).multiply(i).multiply(new v.Matrix(1,0,0,1,-t||0,-e||0))},"native":function(){for(var t=v.parser.draw.node.createSVGMatrix(),e=w.length-1;e>=0;e--)t[w[e]]=this[w[e]];return t},toString:function(){return"matrix("+this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f+")"}},parent:v.Element,construct:{ctm:function(){return new v.Matrix(this.node.getCTM())},screenCTM:function(){return new v.Matrix(this.node.getScreenCTM())}}}),v.Point=v.invent({create:function(t,e){var i,n={x:0,y:0};i=Array.isArray(t)?{x:t[0],y:t[1]}:"object"==typeof t?{x:t.x,y:t.y}:null!=e?{x:t,y:e}:n,this.x=i.x,this.y=i.y},extend:{clone:function(){return new v.Point(this)},morph:function(t){return this.destination=new v.Point(t),this},at:function(t){if(!this.destination)return this;var e=new v.Point({x:this.x+(this.destination.x-this.x)*t,y:this.y+(this.destination.y-this.y)*t});return e},"native":function(){var t=v.parser.draw.node.createSVGPoint();return t.x=this.x,t.y=this.y,t},transform:function(t){return new v.Point(this.native().matrixTransform(t.native()))}}}),v.extend(v.Element,{point:function(t,e){return new v.Point(t,e).transform(this.screenCTM().inverse())}}),v.extend(v.Element,{attr:function(t,e,i){if(null==t){for(t={},e=this.node.attributes,i=e.length-1;i>=0;i--)t[e[i].nodeName]=v.regex.isNumber.test(e[i].nodeValue)?parseFloat(e[i].nodeValue):e[i].nodeValue; | ||
return t}if("object"==typeof t)for(e in t)this.attr(e,t[e]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return e=this.node.getAttribute(t),null==e?v.defaults.attrs[t]:v.regex.isNumber.test(e)?parseFloat(e):e;"stroke-width"==t?this.attr("stroke",parseFloat(e)>0?this._stroke:null):"stroke"==t&&(this._stroke=e),("fill"==t||"stroke"==t)&&(v.regex.isImage.test(e)&&(e=this.doc().defs().image(e,0,0)),e instanceof v.Image&&(e=this.doc().defs().pattern(0,0,function(){this.add(e)}))),"number"==typeof e?e=new v.Number(e):v.Color.isColor(e)?e=new v.Color(e):Array.isArray(e)?e=new v.Array(e):e instanceof v.Matrix&&e.param&&(this.param=e.param),"leading"==t?this.leading&&this.leading(e):"string"==typeof i?this.node.setAttributeNS(i,t,e.toString()):this.node.setAttribute(t,e.toString()),!this.rebuild||"font-size"!=t&&"x"!=t||this.rebuild(t,e)}return this}}),v.extend(v.Element,{transform:function(t,e){var i,n=this;if("object"!=typeof t)return i=new v.Matrix(n).extract(),"string"==typeof t?i[t]:i;if(i=new v.Matrix(n),e=!!e||!!t.relative,null!=t.a)i=e?i.multiply(new v.Matrix(t)):new v.Matrix(t);else if(null!=t.rotation)f(t,n),i=e?i.rotate(t.rotation,t.cx,t.cy):i.rotate(t.rotation-i.extract().rotation,t.cx,t.cy);else if(null!=t.scale||null!=t.scaleX||null!=t.scaleY){if(f(t,n),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 r=i.extract();t.scaleX=1*t.scaleX/r.scaleX,t.scaleY=1*t.scaleY/r.scaleY}i=i.scale(t.scaleX,t.scaleY,t.cx,t.cy)}else if(null!=t.skewX||null!=t.skewY){if(f(t,n),t.skewX=null!=t.skewX?t.skewX:0,t.skewY=null!=t.skewY?t.skewY:0,!e){var r=i.extract();i=i.multiply((new v.Matrix).skew(r.skewX,r.skewY,t.cx,t.cy).inverse())}i=i.skew(t.skewX,t.skewY,t.cx,t.cy)}else t.flip?i=i.flip(t.flip,null==t.offset?n.bbox()["c"+t.flip]:t.offset):(null!=t.x||null!=t.y)&&(e?i=i.translate(t.x,t.y):(null!=t.x&&(i.e=t.x),null!=t.y&&(i.f=t.y)));return this.attr("transform",i)}}),v.extend(v.FX,{transform:function(t,e){var i,n=this.target();return"object"!=typeof t?(i=new v.Matrix(n).extract(),"string"==typeof t?i[t]:i):(e=!!e||!!t.relative,null!=t.a?i=new v.Matrix(t):null!=t.rotation?(f(t,n),i=new v.Rotate(t.rotation,t.cx,t.cy)):null!=t.scale||null!=t.scaleX||null!=t.scaleY?(f(t,n),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,i=new v.Scale(t.scaleX,t.scaleY,t.cx,t.cy)):null!=t.skewX||null!=t.skewY?(f(t,n),t.skewX=null!=t.skewX?t.skewX:0,t.skewY=null!=t.skewY?t.skewY:0,i=new v.Skew(t.skewX,t.skewY,t.cx,t.cy)):t.flip?i=(new v.Matrix).morph((new v.Matrix).flip(t.flip,null==t.offset?n.bbox()["c"+t.flip]:t.offset)):(null!=t.x||null!=t.y)&&(i=new v.Translate(t.x,t.y)),i?(i.relative=e,this.last().transforms.push(i),setTimeout(function(){this.start()}.bind(this),0),this):this)}}),v.extend(v.Element,{untransform:function(){return this.attr("transform",null)},matrixify:function(){var t=(this.attr("transform")||"").split(/\)\s*/).slice(0,-1).map(function(t){var e=t.trim().split("(");return[e[0],e[1].split(v.regex.matrixElements).map(function(t){return parseFloat(t)})]}).reduce(function(t,e){return"matrix"==e[0]?t.multiply(l(e[1])):t[e[0]].apply(t,e[1])},new v.Matrix);return t},toParent:function(t){if(this==t)return this;var e=this.screenCTM(),i=t.rect(1,1),n=i.screenCTM().inverse();return i.remove(),this.addTo(t).untransform().transform(n.multiply(e)),this},toDoc:function(){return this.toParent(this.doc())}}),v.Transformation=v.invent({create:function(t,e){if(arguments.length>1&&"boolean"!=typeof e)return this.create([].slice.call(arguments));if("object"==typeof t)for(var i=0,n=this.arguments.length;n>i;++i)this[this.arguments[i]]=t[this.arguments[i]];if(Array.isArray(t))for(var i=0,n=this.arguments.length;n>i;++i)this[this.arguments[i]]=t[i];this.inversed=!1,e===!0&&(this.inversed=!0)},extend:{at:function(t){for(var e=[],i=0,n=this.arguments.length;n>i;++i)e.push(this[this.arguments[i]]);var r=this._undo||new v.Matrix;return r=(new v.Matrix).morph(v.Matrix.prototype[this.method].apply(r,e)).at(t),this.inversed?r.inverse():r},undo:function(t){return this._undo=new(v[s(this.method)])(t,!0).at(1),this}}}),v.Translate=v.invent({parent:v.Matrix,inherit:v.Transformation,create:function(t,e){"object"==typeof t?this.constructor.call(this,t,e):this.constructor.call(this,[].slice.call(arguments))},extend:{arguments:["transformedX","transformedY"],method:"translate"}}),v.Rotate=v.invent({parent:v.Matrix,inherit:v.Transformation,create:function(t,e){"object"==typeof t?this.constructor.call(this,t,e):this.constructor.call(this,[].slice.call(arguments))},extend:{arguments:["rotation","cx","cy"],method:"rotate",at:function(t){var e=(new v.Matrix).rotate((new v.Number).morph(this.rotation-(this._undo?this._undo.rotation:0)).at(t),this.cx,this.cy);return this.inversed?e.inverse():e},undo:function(t){this._undo=t}}}),v.Scale=v.invent({parent:v.Matrix,inherit:v.Transformation,create:function(t,e){"object"==typeof t?this.constructor.call(this,t,e):this.constructor.call(this,[].slice.call(arguments))},extend:{arguments:["scaleX","scaleY","cx","cy"],method:"scale"}}),v.Skew=v.invent({parent:v.Matrix,inherit:v.Transformation,create:function(t,e){"object"==typeof t?this.constructor.call(this,t,e):this.constructor.call(this,[].slice.call(arguments))},extend:{arguments:["skewX","skewY","cx","cy"],method:"skew"}}),v.extend(v.Element,{style:function(t,e){if(0==arguments.length)return this.node.style.cssText||"";if(arguments.length<2)if("object"==typeof t)for(e in t)this.style(e,t[e]);else{if(!v.regex.isCss.test(t))return this.node.style[r(t)];t=t.split(";");for(var i=0;i<t.length;i++)e=t[i].split(":"),this.style(e[0].replace(/\s+/g,""),e[1])}else this.node.style[r(t)]=null===e||v.regex.isBlank.test(e)?"":e;return this}}),v.Parent=v.invent({create:function(t){this.constructor.call(this,t)},inherit:v.Element,extend:{children:function(){return v.utils.map(v.utils.filterSVGElements(this.node.childNodes),function(t){return v.adopt(t)})},add:function(t,e){return this.has(t)||(e=null==e?this.children().length:e,this.node.insertBefore(t.node,this.node.childNodes[e]||null)),this},put:function(t,e){return this.add(t,e),t},has:function(t){return this.index(t)>=0},index:function(t){return this.children().indexOf(t)},get:function(t){return this.children()[t]},first:function(){return this.children()[0]},last:function(){return this.children()[this.children().length-1]},each:function(t,e){var i,n,r=this.children();for(i=0,n=r.length;n>i;i++)r[i]instanceof v.Element&&t.apply(r[i],[i,r]),e&&r[i]instanceof v.Container&&r[i].each(t,e);return this},removeElement:function(t){return this.node.removeChild(t.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return delete this._defs,this},defs:function(){return this.doc().defs()}}}),v.extend(v.Parent,{ungroup:function(t,e){return 0===e||this instanceof v.Defs?this:(t=t||(this instanceof v.Doc?this:this.parent(v.Parent)),e=e||1/0,this.each(function(){return this instanceof v.Defs?this:this instanceof v.Parent?this.ungroup(t,e-1):this.toParent(t)}),this.node.firstChild||this.remove(),this)},flatten:function(t,e){return this.ungroup(t,e)}}),v.Container=v.invent({create:function(t){this.constructor.call(this,t)},inherit:v.Parent,extend:{viewbox:function(t){return 0==arguments.length?new v.ViewBox(this):(t=1==arguments.length?[t.x,t.y,t.width,t.height]:[].slice.call(arguments),this.attr("viewBox",t))}}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach(function(t){v.Element.prototype[t]=function(e){var i=this;return this.node["on"+t]="function"==typeof e?function(){return e.apply(i,arguments)}:null,this}}),v.listeners=[],v.handlerMap=[],v.listenerId=0,v.on=function(t,e,i,n){var r=i.bind(n||t.instance||t),s=(v.handlerMap.indexOf(t)+1||v.handlerMap.push(t))-1,a=e.split(".")[0],o=e.split(".")[1]||"*";v.listeners[s]=v.listeners[s]||{},v.listeners[s][a]=v.listeners[s][a]||{},v.listeners[s][a][o]=v.listeners[s][a][o]||{},i._svgjsListenerId||(i._svgjsListenerId=++v.listenerId),v.listeners[s][a][o][i._svgjsListenerId]=r,t.addEventListener(a,r,!1)},v.off=function(t,e,i){var n=v.handlerMap.indexOf(t),r=e&&e.split(".")[0],s=e&&e.split(".")[1];if(-1!=n)if(i){if("function"==typeof i&&(i=i._svgjsListenerId),!i)return;v.listeners[n][r]&&v.listeners[n][r][s||"*"]&&(t.removeEventListener(r,v.listeners[n][r][s||"*"][i],!1),delete v.listeners[n][r][s||"*"][i])}else if(s&&r){if(v.listeners[n][r]&&v.listeners[n][r][s]){for(i in v.listeners[n][r][s])v.off(t,[r,s].join("."),i);delete v.listeners[n][r][s]}}else if(s)for(e in v.listeners[n])for(namespace in v.listeners[n][e])s===namespace&&v.off(t,[e,s].join("."));else if(r){if(v.listeners[n][r]){for(namespace in v.listeners[n][r])v.off(t,[r,namespace].join("."));delete v.listeners[n][r]}}else{for(e in v.listeners[n])v.off(t,e);delete v.listeners[n]}},v.extend(v.Element,{on:function(t,e,i){return v.on(this.node,t,e,i),this},off:function(t,e){return v.off(this.node,t,e),this},fire:function(t,e){return t instanceof Event?this.node.dispatchEvent(t):this.node.dispatchEvent(new b(t,{detail:e})),this}}),v.Defs=v.invent({create:"defs",inherit:v.Container}),v.G=v.invent({create:"g",inherit:v.Container,extend:{x:function(t){return null==t?this.transform("x"):this.transform({x:t-this.x()},!0)},y:function(t){return null==t?this.transform("y"):this.transform({y:t-this.y()},!0)},cx:function(t){return null==t?this.gbox().cx:this.x(t-this.gbox().width/2)},cy:function(t){return null==t?this.gbox().cy:this.y(t-this.gbox().height/2)},gbox:function(){var t=this.bbox(),e=this.transform();return t.x+=e.x,t.x2+=e.x,t.cx+=e.x,t.y+=e.y,t.y2+=e.y,t.cy+=e.y,t}},construct:{group:function(){return this.put(new v.G)}}}),v.extend(v.Element,{siblings:function(){return this.parent().children()},position:function(){return this.parent().index(this)},next:function(){return this.siblings()[this.position()+1]},previous:function(){return this.siblings()[this.position()-1]},forward:function(){var t=this.position()+1,e=this.parent();return e.removeElement(this).add(this,t),e instanceof v.Doc&&e.node.appendChild(e.defs().node),this},backward:function(){var t=this.position();return t>0&&this.parent().removeElement(this).add(this,t-1),this},front:function(){var t=this.parent();return t.node.appendChild(this.node),t instanceof v.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}}),v.Mask=v.invent({create:function(){this.constructor.call(this,v.create("mask")),this.targets=[]},inherit:v.Container,extend:{remove:function(){for(var t=this.targets.length-1;t>=0;t--)this.targets[t]&&this.targets[t].unmask();return this.targets=[],this.parent().removeElement(this),this}},construct:{mask:function(){return this.defs().put(new v.Mask)}}}),v.extend(v.Element,{maskWith:function(t){return this.masker=t instanceof v.Mask?t:this.parent().mask().add(t),this.masker.targets.push(this),this.attr("mask",'url("#'+this.masker.attr("id")+'")')},unmask:function(){return delete this.masker,this.attr("mask",null)}}),v.ClipPath=v.invent({create:function(){this.constructor.call(this,v.create("clipPath")),this.targets=[]},inherit:v.Container,extend:{remove:function(){for(var t=this.targets.length-1;t>=0;t--)this.targets[t]&&this.targets[t].unclip();return this.targets=[],this.parent().removeElement(this),this}},construct:{clip:function(){return this.defs().put(new v.ClipPath)}}}),v.extend(v.Element,{clipWith:function(t){return this.clipper=t instanceof v.ClipPath?t:this.parent().clip().add(t),this.clipper.targets.push(this),this.attr("clip-path",'url("#'+this.clipper.attr("id")+'")')},unclip:function(){return delete this.clipper,this.attr("clip-path",null)}}),v.Gradient=v.invent({create:function(t){this.constructor.call(this,v.create(t+"Gradient")),this.type=t},inherit:v.Container,extend:{at:function(t,e,i){return this.put(new v.Stop).update(t,e,i)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},fill:function(){return"url(#"+this.id()+")"},toString:function(){return this.fill()},attr:function(t,e,i){return"transform"==t&&(t="gradientTransform"),v.Container.prototype.attr.call(this,t,e,i)}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),v.extend(v.Gradient,v.FX,{from:function(t,e){return"radial"==(this.target||this).type?this.attr({fx:new v.Number(t),fy:new v.Number(e)}):this.attr({x1:new v.Number(t),y1:new v.Number(e)})},to:function(t,e){return"radial"==(this.target||this).type?this.attr({cx:new v.Number(t),cy:new v.Number(e)}):this.attr({x2:new v.Number(t),y2:new v.Number(e)})}}),v.extend(v.Defs,{gradient:function(t,e){return this.put(new v.Gradient(t)).update(e)}}),v.Stop=v.invent({create:"stop",inherit:v.Element,extend:{update:function(t){return("number"==typeof t||t instanceof v.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 v.Number(t.offset)),this}}}),v.Pattern=v.invent({create:"pattern",inherit:v.Container,extend:{fill:function(){return"url(#"+this.id()+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.fill()},attr:function(t,e,i){return"transform"==t&&(t="patternTransform"),v.Container.prototype.attr.call(this,t,e,i)}},construct:{pattern:function(t,e,i){return this.defs().pattern(t,e,i)}}}),v.extend(v.Defs,{pattern:function(t,e,i){return this.put(new v.Pattern).update(i).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),v.Doc=v.invent({create:function(t){t&&(t="string"==typeof t?e.getElementById(t):t,"svg"==t.nodeName?this.constructor.call(this,t):(this.constructor.call(this,v.create("svg")),t.appendChild(this.node)),this.namespace().size("100%","100%").defs())},inherit:v.Container,extend:{namespace:function(){return this.attr({xmlns:v.ns,version:"1.1"}).attr("xmlns:xlink",v.xlink,v.xmlns).attr("xmlns:svgjs",v.svgjs,v.xmlns)},defs:function(){if(!this._defs){var t;this._defs=(t=this.node.getElementsByTagName("defs")[0])?v.adopt(t):new v.Defs,this.node.appendChild(this._defs.node)}return this._defs},parent:function(){return"#document"==this.node.parentNode.nodeName?null:this.node.parentNode},spof:function(){var t=this.node.getScreenCTM();return t&&this.style("left",-t.e%1+"px").style("top",-t.f%1+"px"),this},remove:function(){return this.parent()&&this.parent().removeChild(this.node),this}}}),v.Shape=v.invent({create:function(t){this.constructor.call(this,t)},inherit:v.Element}),v.Bare=v.invent({create:function(t,e){if(this.constructor.call(this,v.create(t)),e)for(var i in e.prototype)"function"==typeof e.prototype[i]&&(this[i]=e.prototype[i])},inherit:v.Element,extend:{words:function(t){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this.node.appendChild(e.createTextNode(t)),this}}}),v.extend(v.Parent,{element:function(t,e){return this.put(new v.Bare(t,e))},symbol:function(){return this.defs().element("symbol",v.Container)}}),v.Use=v.invent({create:"use",inherit:v.Shape,extend:{element:function(t,e){return this.attr("href",(e||"")+"#"+t,v.xlink)}},construct:{use:function(t,e){return this.put(new v.Use).element(t,e)}}}),v.Rect=v.invent({create:"rect",inherit:v.Shape,construct:{rect:function(t,e){return this.put(new v.Rect).size(t,e)}}}),v.Circle=v.invent({create:"circle",inherit:v.Shape,construct:{circle:function(t){return this.put(new v.Circle).rx(new v.Number(t).divide(2)).move(0,0)}}}),v.extend(v.Circle,v.FX,{rx:function(t){return this.attr("r",t)},ry:function(t){return this.rx(t)}}),v.Ellipse=v.invent({create:"ellipse",inherit:v.Shape,construct:{ellipse:function(t,e){return this.put(new v.Ellipse).size(t,e).move(0,0)}}}),v.extend(v.Ellipse,v.Rect,v.FX,{rx:function(t){return this.attr("rx",t)},ry:function(t){return this.attr("ry",t)}}),v.extend(v.Circle,v.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 v.Number(t).divide(2))},height:function(t){return null==t?2*this.ry():this.ry(new v.Number(t).divide(2))},size:function(t,e){var i=h(this.bbox(),t,e);return this.rx(new v.Number(i.width).divide(2)).ry(new v.Number(i.height).divide(2))}}),v.Line=v.invent({create:"line",inherit:v.Shape,extend:{array:function(){return new v.PointArray([[this.attr("x1"),this.attr("y1")],[this.attr("x2"),this.attr("y2")]])},plot:function(t,e,i,n){return t=4==arguments.length?{x1:t,y1:e,x2:i,y2:n}:new v.PointArray(t).toLine(),this.attr(t)},move:function(t,e){return this.attr(this.array().move(t,e).toLine())},size:function(t,e){var i=h(this.bbox(),t,e);return this.attr(this.array().size(i.width,i.height).toLine())}},construct:{line:function(t,e,i,n){return this.put(new v.Line).plot(t,e,i,n)}}}),v.Polyline=v.invent({create:"polyline",inherit:v.Shape,construct:{polyline:function(t){return this.put(new v.Polyline).plot(t)}}}),v.Polygon=v.invent({create:"polygon",inherit:v.Shape,construct:{polygon:function(t){return this.put(new v.Polygon).plot(t)}}}),v.extend(v.Polyline,v.Polygon,{array:function(){return this._array||(this._array=new v.PointArray(this.attr("points")))},plot:function(t){return this.attr("points",this._array=new v.PointArray(t))},move:function(t,e){return this.attr("points",this.array().move(t,e))},size:function(t,e){var i=h(this.bbox(),t,e);return this.attr("points",this.array().size(i.width,i.height))}}),v.extend(v.Line,v.Polyline,v.Polygon,{morphArray:v.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)}}),v.Path=v.invent({create:"path",inherit:v.Shape,extend:{morphArray:v.PathArray,array:function(){return this._array||(this._array=new v.PathArray(this.attr("d")))},plot:function(t){return this.attr("d",this._array=new v.PathArray(t))},move:function(t,e){return this.attr("d",this.array().move(t,e))},x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},size:function(t,e){var i=h(this.bbox(),t,e);return this.attr("d",this.array().size(i.width,i.height))},width:function(t){return null==t?this.bbox().width:this.size(t,this.bbox().height)},height:function(t){return null==t?this.bbox().height:this.size(this.bbox().width,t)}},construct:{path:function(t){return this.put(new v.Path).plot(t)}}}),v.Image=v.invent({create:"image",inherit:v.Shape,extend:{load:function(t){if(!t)return this;var i=this,n=e.createElement("img");return n.onload=function(){var e=i.parent(v.Pattern);null!==e&&(0==i.width()&&0==i.height()&&i.size(n.width,n.height),e&&0==e.width()&&0==e.height()&&e.size(i.width(),i.height()),"function"==typeof i._loaded&&i._loaded.call(i,{width:n.width,height:n.height,ratio:n.width/n.height,url:t}))},this.attr("href",n.src=this.src=t,v.xlink)},loaded:function(t){return this._loaded=t,this}},construct:{image:function(t,e,i){return this.put(new v.Image).load(t).size(e||0,i||e||0)}}}),v.Text=v.invent({create:function(){this.constructor.call(this,v.create("text")),this.dom.leading=new v.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",v.defaults.attrs["font-family"])},inherit:v.Shape,extend:{clone:function(){var t=m(this.node.cloneNode(!0));return this.after(t),t},x:function(t){return null==t?this.attr("x"):(this.textPath||this.lines().each(function(){this.dom.newLined&&this.x(t)}),this.attr("x",t))},y:function(t){var e=this.attr("y"),i="number"==typeof e?e-this.bbox().y:0;return null==t?"number"==typeof e?e-i:e:this.attr("y","number"==typeof t?t+i:t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)},text:function(t){if("undefined"==typeof t){for(var t="",e=this.node.childNodes,i=0,n=e.length;n>i;++i)0!=i&&3!=e[i].nodeType&&1==v.adopt(e[i]).dom.newLined&&(t+="\n"),t+=e[i].textContent;return t}if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{t=t.split("\n");for(var i=0,r=t.length;r>i;i++)this.tspan(t[i]).newLine()}return this.build(!1).rebuild()},size:function(t){return this.attr("font-size",t).rebuild()},leading:function(t){return null==t?this.dom.leading:(this.dom.leading=new v.Number(t),this.rebuild())},lines:function(){var t=(this.textPath&&this.textPath()||this).node,e=v.utils.map(v.utils.filterSVGElements(t.childNodes),function(t){return v.adopt(t)});return new v.Set(e)},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this,i=0,n=this.dom.leading*new v.Number(this.attr("font-size"));this.lines().each(function(){this.dom.newLined&&(this.textPath||this.attr("x",e.attr("x")),"\n"==this.text()?i+=n:(this.attr("dy",n+i),i=0))}),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this},setData:function(t){return this.dom=t,this.dom.leading=new v.Number(t.leading||1.3),this}},construct:{text:function(t){return this.put(new v.Text).text(t)},plain:function(t){return this.put(new v.Text).plain(t)}}}),v.Tspan=v.invent({create:"tspan",inherit:v.Shape,extend:{text:function(t){return null==t?this.node.textContent+(this.dom.newLined?"\n":""):("function"==typeof t?t.call(this,this):this.plain(t),this)},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.parent(v.Text);return this.dom.newLined=!0,this.dy(t.dom.leading*t.attr("font-size")).attr("x",t.x())}}}),v.extend(v.Text,v.Tspan,{plain:function(t){return this._build===!1&&this.clear(),this.node.appendChild(e.createTextNode(t)),this},tspan:function(t){var e=(this.textPath&&this.textPath()||this).node,i=new v.Tspan;return this._build===!1&&this.clear(),e.appendChild(i.node),i.text(t)},clear:function(){for(var t=(this.textPath&&this.textPath()||this).node;t.hasChildNodes();)t.removeChild(t.lastChild);return this},length:function(){return this.node.getComputedTextLength()}}),v.TextPath=v.invent({create:"textPath",inherit:v.Parent,parent:v.Text,construct:{path:function(t){for(var e=new v.TextPath,i=this.doc().defs().path(t);this.node.hasChildNodes();)e.node.appendChild(this.node.firstChild);return this.node.appendChild(e.node),e.attr("href","#"+i,v.xlink),this},plot:function(t){var e=this.track();return e&&e.plot(t),this},track:function(){var t=this.textPath();return t?t.reference("href"):void 0},textPath:function(){return this.node.firstChild&&"textPath"==this.node.firstChild.nodeName?v.adopt(this.node.firstChild):void 0}}}),v.Nested=v.invent({create:function(){this.constructor.call(this,v.create("svg")),this.style("overflow","visible")},inherit:v.Container,construct:{nested:function(){return this.put(new v.Nested)}}}),v.A=v.invent({create:"a",inherit:v.Container,extend:{to:function(t){return this.attr("href",t,v.xlink)},show:function(t){return this.attr("show",t,v.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new v.A).to(t)}}}),v.extend(v.Element,{linkTo:function(t){var e=new v.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent().put(e).put(this)}}),v.Marker=v.invent({create:"marker",inherit:v.Container,extend:{width:function(t){return this.attr("markerWidth",t)},height:function(t){return this.attr("markerHeight",t)},ref:function(t,e){return this.attr("refX",t).attr("refY",e)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return"url(#"+this.id()+")"}},construct:{marker:function(t,e,i){return this.defs().marker(t,e,i)}}}),v.extend(v.Defs,{marker:function(t,e,i){return this.put(new v.Marker).size(t,e).ref(t/2,e/2).viewbox(0,0,t,e).attr("orient","auto").update(i)}}),v.extend(v.Line,v.Polyline,v.Polygon,v.Path,{marker:function(t,e,i,n){var r=["marker"];return"all"!=t&&r.push(t),r=r.join("-"),t=arguments[1]instanceof v.Marker?arguments[1]:this.doc().marker(e,i,n),this.attr(r,t)}});var y={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(t,e){return"color"==e?t:t+"-"+e}};["fill","stroke"].forEach(function(t){var e,i={};i[t]=function(i){if("string"==typeof i||v.Color.isRgb(i)||i&&"function"==typeof i.fill)this.attr(t,i);else for(e=y[t].length-1;e>=0;e--)null!=i[y[t][e]]&&this.attr(y.prefix(t,y[t][e]),i[y[t][e]]);return this},v.extend(v.Element,v.FX,i)}),v.extend(v.Element,v.FX,{rotate:function(t,e,i){return this.transform({rotation:t,cx:e,cy:i})},skew:function(t,e,i,n){return this.transform({skewX:t,skewY:e,cx:i,cy:n})},scale:function(t,e,i,n){return 1==arguments.length||3==arguments.length?this.transform({scale:t,cx:e,cy:i}):this.transform({scaleX:t,scaleY:e,cx:i,cy:n})},translate:function(t,e){return this.transform({x:t,y:e})},flip:function(t,e){return this.transform({flip:t,offset:e})},matrix:function(t){return this.attr("transform",new v.Matrix(t))},opacity:function(t){return this.attr("opacity",t)},dx:function(t){return this.x((this instanceof v.FX?0:this.x())+t,!0)},dy:function(t){return this.y((this instanceof v.FX?0:this.y())+t,!0)},dmove:function(t,e){return this.dx(t).dy(e)}}),v.extend(v.Rect,v.Ellipse,v.Circle,v.Gradient,v.FX,{radius:function(t,e){var i=(this.target||this).type;return"radial"==i||"circle"==i?this.attr({r:new v.Number(t)}):this.rx(t).ry(null==e?t:e)}}),v.extend(v.Path,{length:function(){return this.node.getTotalLength()},pointAt:function(t){return this.node.getPointAtLength(t)}}),v.extend(v.Parent,v.Text,v.FX,{font:function(t){for(var e in t)"leading"==e?this.leading(t[e]):"anchor"==e?this.attr("text-anchor",t[e]):"size"==e||"family"==e||"weight"==e||"stretch"==e||"variant"==e||"style"==e?this.attr("font-"+e,t[e]):this.attr(e,t[e]);return this}}),v.Set=v.invent({create:function(t){Array.isArray(t)?this.members=t:this.clear()},extend:{add:function(){var t,e,i=[].slice.call(arguments);for(t=0,e=i.length;e>t;t++)this.members.push(i[t]);return this},remove:function(t){var e=this.index(t);return e>-1&&this.members.splice(e,1),this},each:function(t){for(var e=0,i=this.members.length;i>e;e++)t.apply(this.members[e],[e,this.members]);return this},clear:function(){return this.members=[],this},length:function(){return this.members.length},has:function(t){return this.index(t)>=0},index:function(t){return this.members.indexOf(t)},get:function(t){return this.members[t]},first:function(){return this.get(0)},last:function(){return this.get(this.members.length-1)},valueOf:function(){return this.members},bbox:function(){var t=new v.BBox;if(0==this.members.length)return t;var e=this.members[0].rbox();return t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,this.each(function(){t=t.merge(this.rbox())}),t}},construct:{set:function(t){return new v.Set(t)}}}),v.FX.Set=v.invent({create:function(t){this.set=t}}),v.Set.inherit=function(){var t,e=[];for(var t in v.Shape.prototype)"function"==typeof v.Shape.prototype[t]&&"function"!=typeof v.Set.prototype[t]&&e.push(t);e.forEach(function(t){v.Set.prototype[t]=function(){for(var e=0,i=this.members.length;i>e;e++)this.members[e]&&"function"==typeof this.members[e][t]&&this.members[e][t].apply(this.members[e],arguments);return"animate"==t?this.fx||(this.fx=new v.FX.Set(this)):this}}),e=[];for(var t in v.FX.prototype)"function"==typeof v.FX.prototype[t]&&"function"!=typeof v.FX.Set.prototype[t]&&e.push(t);e.forEach(function(t){v.FX.Set.prototype[t]=function(){for(var e=0,i=this.set.members.length;i>e;e++)this.set.members[e].fx[t].apply(this.set.members[e].fx,arguments);return this}})},v.extend(v.Element,{data:function(t,e,i){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+t))}catch(n){return this.attr("data-"+t)}else this.attr("data-"+t,null===e?null:i===!0||"string"==typeof e||"number"==typeof e?e:JSON.stringify(e));return this}}),v.extend(v.Element,{remember:function(t,e){if("object"==typeof arguments[0])for(var e in t)this.remember(e,t[e]);else{if(1==arguments.length)return this.memory()[t];this.memory()[t]=e}return this},forget:function(){if(0==arguments.length)this._memory={};else for(var t=arguments.length-1;t>=0;t--)delete this.memory()[arguments[t]];return this},memory:function(){return this._memory||(this._memory={})}}),v.get=function(t){var i=e.getElementById(g(t)||t);return v.adopt(i)},v.select=function(t,i){return new v.Set(v.utils.map((i||e).querySelectorAll(t),function(t){return v.adopt(t)}))},v.extend(v.Parent,{select:function(t){return v.select(t,this.node)}});var w="abcdef".split("");if("function"!=typeof b){var b=function(t,i){i=i||{bubbles:!1,cancelable:!1,detail:void 0};var n=e.createEvent("CustomEvent");return n.initCustomEvent(t,i.bubbles,i.cancelable,i.detail),n};b.prototype=t.Event.prototype,t.CustomEvent=b}return function(e){for(var i=0,n=["moz","webkit"],r=0;r<n.length&&!t.requestAnimationFrame;++r)e.requestAnimationFrame=e[n[r]+"RequestAnimationFrame"],e.cancelAnimationFrame=e[n[r]+"CancelAnimationFrame"]||e[n[r]+"CancelRequestAnimationFrame"];e.requestAnimationFrame=e.requestAnimationFrame||function(t){var n=(new Date).getTime(),r=Math.max(0,16-(n-i)),s=e.setTimeout(function(){t(n+r)},r);return i=n+r,s},e.cancelAnimationFrame=e.cancelAnimationFrame||e.clearTimeout}(t),v}); |
@@ -47,2 +47,3 @@ var del = require('del') | ||
, 'src/matrix.js' | ||
, 'src/point.js' | ||
, 'src/attr.js' | ||
@@ -49,0 +50,0 @@ , 'src/transform.js' |
{ | ||
"name": "svg.js", | ||
"version": "2.2.5", | ||
"version": "2.3.0", | ||
"description": "A lightweight library for manipulating and animating SVG.", | ||
@@ -13,3 +13,3 @@ "url": "http://svgjs.com", | ||
], | ||
"author": "Wout Fierens <wout@impinc.co.uk>", | ||
"author": "Wout Fierens <wout@woutfierens.com>", | ||
"main": "dist/svg.js", | ||
@@ -16,0 +16,0 @@ "jam": { |
describe('Element', function() { | ||
beforeEach(function() { | ||
@@ -10,3 +10,3 @@ draw.attr('viewBox', null) | ||
}) | ||
it('should create a circular reference on the node', function() { | ||
@@ -23,6 +23,6 @@ var rect = draw.rect(100,100) | ||
}) | ||
describe('attr()', function() { | ||
var rect | ||
beforeEach(function() { | ||
@@ -108,7 +108,7 @@ rect = draw.rect(100,100) | ||
var rect | ||
beforeEach(function() { | ||
rect = draw.rect(100,100) | ||
}) | ||
it('gets the value if the id attribute without an argument', function() { | ||
@@ -122,3 +122,3 @@ expect(rect.id()).toBe(rect.attr('id')) | ||
}) | ||
describe('style()', function() { | ||
@@ -156,10 +156,10 @@ it('sets the style with key and value arguments', function() { | ||
}) | ||
describe('transform()', function() { | ||
var rect, ctm | ||
beforeEach(function() { | ||
rect = draw.rect(100,100) | ||
}) | ||
it('gets the current transformations', function() { | ||
@@ -254,3 +254,3 @@ expect(rect.transform()).toEqual(new SVG.Matrix(rect).extract()) | ||
var circle | ||
beforeEach(function() { | ||
@@ -274,7 +274,7 @@ circle = draw.circle(100).translate(50, 100) | ||
var rect | ||
beforeEach(function() { | ||
rect = draw.rect(100, 100) | ||
}) | ||
it('gets the current transform matrix of the element', function() { | ||
@@ -288,3 +288,3 @@ rect.translate(10, 20) | ||
}) | ||
describe('data()', function() { | ||
@@ -321,6 +321,6 @@ it('sets a data attribute and convert value to json', function() { | ||
expect(typeof rect.data('test')).toBe('object') | ||
expect(Array.isArray(rect.data('test').array)).toBe(true) | ||
expect(Array.isArray(rect.data('test').array)).toBe(true) | ||
}) | ||
}) | ||
describe('remove()', function() { | ||
@@ -357,3 +357,3 @@ it('removes an element and return it', function() { | ||
}) | ||
describe('rbox()', function() { | ||
@@ -385,3 +385,3 @@ it('returns an instance of SVG.RBox', function() { | ||
}) | ||
describe('doc()', function() { | ||
@@ -393,3 +393,3 @@ it('returns the parent document', function() { | ||
}) | ||
describe('parent()', function() { | ||
@@ -417,3 +417,3 @@ it('contains the parent svg', function() { | ||
}) | ||
describe('parents()', function() { | ||
@@ -431,3 +431,3 @@ it('returns array of parent up to but not including the dom element filtered by type', function() { | ||
}) | ||
describe('clone()', function() { | ||
@@ -480,3 +480,3 @@ var rect, group, circle | ||
rect.replace(circle) | ||
expect(rectIndex).toBe(draw.children().indexOf(circle)) | ||
@@ -488,3 +488,3 @@ }) | ||
rect.replace(draw.circle(200)) | ||
expect(draw.has(rect)).toBe(false) | ||
@@ -495,3 +495,3 @@ }) | ||
var element = draw.rect(100,100).center(321,567).fill('#f06').replace(circle) | ||
expect(element).toBe(circle) | ||
@@ -636,2 +636,34 @@ }) | ||
}) | ||
describe('writeDataToDom()', function() { | ||
it('set all properties in el.dom to the svgjs:data attribute', function(){ | ||
var rect = draw.rect(100,100) | ||
rect.dom.foo = 'bar' | ||
rect.dom.number = new SVG.Number('3px') | ||
rect.writeDataToDom() | ||
expect(rect.attr('svgjs:data')).toBe('{"foo":"bar","number":"3px"}') | ||
}) | ||
}) | ||
describe('setData()', function() { | ||
it('read all data from the svgjs:data attribute and assign it to el.dom', function(){ | ||
var rect = draw.rect(100,100) | ||
rect.attr('svgjs:data', '{"foo":"bar","number":"3px"}') | ||
rect.setData(JSON.parse(rect.attr('svgjs:data'))) | ||
expect(rect.dom.foo).toBe('bar') | ||
expect(rect.dom.number).toBe('3px') | ||
}) | ||
}) | ||
describe('point()', function() { | ||
it('creates a point from screen coordinates transformed in the elements space', function(){ | ||
var rect = draw.rect(100,100) | ||
expect(rect.point(2,5).x).toBeCloseTo(-6) | ||
expect(rect.point(2,5).y).toBeCloseTo(-21) | ||
}) | ||
}) | ||
}) |
@@ -300,6 +300,6 @@ describe('Event', function() { | ||
var listenerCnt = SVG.listeners.length | ||
var rect2 = draw.rect(100,100); | ||
var rect3 = draw.rect(100,100); | ||
rect.on('event', action) | ||
@@ -309,5 +309,7 @@ rect2.on('event', action) | ||
rect3.on('event', action) | ||
expect(Object.keys(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['*']).length).toBe(1) // 1 listener on rect | ||
expect(Object.keys(SVG.listeners[SVG.handlerMap.indexOf(rect2.node)]['event']['*']).length).toBe(1) // 1 listener on rect2 | ||
expect(Object.keys(SVG.listeners[SVG.handlerMap.indexOf(rect3.node)]['event']['*']).length).toBe(2) // 2 listener on rect3 | ||
expect(SVG.listeners.length).toBe(listenerCnt + 3) // added listeners on 3 different elements | ||
@@ -317,6 +319,6 @@ }) | ||
var listenerCnt = SVG.listeners.length | ||
var rect2 = draw.rect(100,100); | ||
var rect3 = draw.rect(100,100); | ||
rect.on('event.namespace1', action) | ||
@@ -326,3 +328,3 @@ rect2.on('event.namespace2', action) | ||
rect3.on('event', action) | ||
expect(Object.keys(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['*'])).toBeUndefined() // no global listener on rect | ||
@@ -345,3 +347,3 @@ expect(Object.keys(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['namespace1']).length).toBe( 1) // 1 namespaced listener on rect | ||
rect.on('event', action) | ||
expect(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['*'][action]).not.toBeUndefined() | ||
expect(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['*'][action._svgjsListenerId]).not.toBeUndefined() | ||
}) | ||
@@ -363,20 +365,20 @@ it('returns the called element', function() { | ||
rect3 = draw.rect(100,100); | ||
rect.on('event', action) | ||
rect2.on('event', action) | ||
rect3.on('event', function(){ butter = 'melting' }) | ||
rect.off('event', action) | ||
expect(Object.keys(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['*']).length).toBe(0) | ||
dispatchEvent(rect, 'event') | ||
expect(toast).toBeNull() | ||
dispatchEvent(rect2, 'event') | ||
expect(toast).toBe('ready') | ||
dispatchEvent(rect3, 'event') | ||
expect(butter).toBe('melting') | ||
expect(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['*'][action]).toBeUndefined() | ||
@@ -387,20 +389,20 @@ }) | ||
rect3 = draw.rect(100,100); | ||
rect.on('event.namespace', action) | ||
rect2.on('event.namespace', action) | ||
rect3.on('event.namespace', function(){ butter = 'melting' }) | ||
rect.off('event.namespace', action) | ||
expect(Object.keys(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['namespace']).length).toBe(0) | ||
dispatchEvent(rect, 'event') | ||
expect(toast).toBeNull() | ||
dispatchEvent(rect2, 'event') | ||
expect(toast).toBe('ready') | ||
dispatchEvent(rect3, 'event') | ||
expect(butter).toBe('melting') | ||
expect(SVG.listeners[SVG.handlerMap.indexOf(rect.node)]['event']['namespace'][action]).toBeUndefined() | ||
@@ -469,4 +471,4 @@ }) | ||
}) | ||
}) | ||
@@ -473,0 +475,0 @@ |
@@ -9,16 +9,256 @@ describe('FX', function() { | ||
it('creates an instance of SVG.FX', function() { | ||
it('creates an instance of SVG.FX and sets parameter', function() { | ||
expect(fx instanceof SVG.FX).toBe(true) | ||
expect(fx._target).toBe(rect) | ||
expect(fx.pos).toBe(0) | ||
expect(fx.lastPos).toBe(0) | ||
expect(fx.paused).toBeFalsy() | ||
expect(fx.active).toBeFalsy() | ||
expect(fx.situations).toEqual([]) | ||
expect(fx.situation.init).toBeFalsy() | ||
expect(fx.situation.reversed).toBeFalsy() | ||
expect(fx.situation.duration).toBe(500) | ||
expect(fx.situation.delay).toBe(0) | ||
expect(fx.situation.animations).toEqual({}) | ||
expect(fx.situation.attrs).toEqual({}) | ||
expect(fx.situation.styles).toEqual({}) | ||
expect(fx.situation.transforms).toEqual([]) | ||
expect(fx.situation.once).toEqual({}) | ||
}) | ||
describe('target()', function(){ | ||
it('returns the current fx object with no argument given', function(){ | ||
expect(fx.target()).toBe(rect) | ||
}) | ||
it('changes the target of the animation when parameter given', function(){ | ||
var c = draw.circle(5) | ||
expect(fx.target(c).target()).toBe(c) | ||
}) | ||
}) | ||
describe('timeToPos()', function() { | ||
it('converts a timestamp to a progress', function() { | ||
expect(fx.timeToPos(fx.situation.start+fx.situation.duration/2)).toBe(0.5) | ||
}) | ||
}) | ||
describe('posToTime()', function() { | ||
it('converts a progress to a timestamp', function() { | ||
expect(fx.posToTime(0.5)).toBe(fx.situation.start+fx.situation.duration/2) | ||
}) | ||
}) | ||
describe('at()', function() { | ||
it('sets the progress to the specified position', function() { | ||
var start = fx.situation.start | ||
expect(fx.at(0.5).pos).toBe(0.5) | ||
// time is running so we cant compare it directly | ||
expect(fx.situation.start).toBeLessThan(start - fx.situation.duration * 0.5 + 1) | ||
expect(fx.situation.start).toBeGreaterThan(start - fx.situation.duration * 0.5 - 10) | ||
}) | ||
}) | ||
describe('start()', function(){ | ||
it('starts the animation', function(done) { | ||
fx.start() | ||
expect(fx.active).toBe(true) | ||
expect(fx.timeout).not.toBe(0) | ||
setTimeout(function(){ | ||
expect(fx.pos).toBeGreaterThan(0) | ||
done() | ||
}, 200) | ||
}) | ||
}) | ||
describe('pause()', function() { | ||
it('pause the animation', function() { | ||
expect(fx.pause().paused).toBe(true) | ||
}) | ||
}) | ||
describe('play()', function() { | ||
it('unpause the animation', function(done) { | ||
var start = fx.start().pause().situation.start | ||
setTimeout(function(){ | ||
expect(fx.play().paused).toBe(false) | ||
expect(fx.situation.start).not.toBe(start) | ||
done() | ||
}, 200) | ||
}) | ||
}) | ||
describe('speed()', function() { | ||
it('speeds up the animation by the given factor', function(){ | ||
expect(fx.speed(2).situation.duration).toBe(250) | ||
expect(fx.speed(0.5).situation.duration).toBe(500) | ||
expect(fx.at(0.2).speed(2).situation.duration).toBe(0.2 * 500 + 0.8 * 500 / 2) | ||
}) | ||
}) | ||
describe('reverse()', function() { | ||
it('toggles the direction of the animation without a parameter', function() { | ||
expect(fx.reverse().situation.reversed).toBe(true) | ||
}) | ||
}) | ||
describe('reverse()', function() { | ||
it('sets the direction to backwards with true given', function() { | ||
expect(fx.reverse(true).situation.reversed).toBe(true) | ||
}) | ||
}) | ||
describe('reverse()', function() { | ||
it('sets the direction to forwards with false given', function() { | ||
expect(fx.reverse(false).situation.reversed).toBe(false) | ||
}) | ||
}) | ||
describe('stop()', function() { | ||
it('stops the animation immediately without a parameter', function() { | ||
fx.animate(500) | ||
expect(fx.stop().situation).toBeNull() | ||
expect(fx.active).toBeFalsy() | ||
expect(fx.situations.length).toBe(1) | ||
}) | ||
}) | ||
describe('stop()', function() { | ||
it('stops the animation immediately and fullfill it if first parameter true', function() { | ||
fx.animate(500) | ||
expect(fx.stop(true).situation).toBeNull() | ||
expect(fx.active).toBeFalsy() | ||
expect(fx.pos).toBe(1) | ||
expect(fx.situations.length).toBe(1) | ||
}) | ||
}) | ||
describe('stop()', function() { | ||
it('stops the animation immediately and remove all items from queue when second parameter true', function() { | ||
fx.animate(500) | ||
expect(fx.stop(false, true).situation).toBeNull() | ||
expect(fx.active).toBeFalsy() | ||
expect(fx.situations.length).toBe(0) | ||
}) | ||
}) | ||
describe('finish()', function() { | ||
it('finish the whole animation by fullfilling every single one', function() { | ||
fx.animate(500) | ||
expect(fx.finish().pos).toBe(1) | ||
expect(fx.situations.length).toBe(0) | ||
expect(fx.situation).toBeNull() | ||
}) | ||
}) | ||
describe('progress()', function() { | ||
it('returns the current position', function() { | ||
expect(fx.progress()).toBe(0) | ||
expect(fx.progress()).toBe(fx.pos) | ||
}) | ||
}) | ||
describe('after()', function() { | ||
it('adds a callback which is called when the current animation is finished', function(done) { | ||
fx.start().after(function(situation){ | ||
expect(fx.situation).toBe(situation) | ||
expect(fx.pos).toBe(1) | ||
done() | ||
}) | ||
}) | ||
}) | ||
describe('afterAll()', function() { | ||
it('adds a callback which is called when all animations are finished', function(done) { | ||
fx.start().after(function(){ | ||
expect(fx.pos).toBe(1) | ||
expect(fx.situations.length).toBe(0) | ||
done() | ||
}) | ||
}) | ||
}) | ||
describe('during()', function() { | ||
it('adds a callback which is called on every animation step', function(done) { | ||
fx.start().during(function(pos, morph, eased, situation){ | ||
expect(fx.situation).toBe(situation) | ||
if(fx.pos > 0.9){ | ||
rect.off('.fx') | ||
fx.stop() | ||
done() | ||
} | ||
}) | ||
}) | ||
}) | ||
describe('duringAll()', function() { | ||
it('adds a callback which is called on every animation step for the whole chain', function(done) { | ||
fx.finish() | ||
rect.off('.fx') | ||
fx.animate(500).start().animate(500) | ||
var sit = null | ||
var pos1 = false | ||
var pos2 = false | ||
setTimeout(function(){ | ||
pos1 = true | ||
}, 300) | ||
setTimeout(function(){ | ||
pos2 = true | ||
}, 800) | ||
fx.duringAll(function(pos, morph, eased, situation){ | ||
if(pos1){ | ||
pos1 = false | ||
sit = situation | ||
expect(this.fx.pos).toBeGreaterThan(0.5) | ||
} | ||
if(pos2){ | ||
pos2 = null | ||
expect(situation).not.toBe(sit) | ||
expect(this.fx.pos).toBeGreaterThan(0.5) | ||
done() | ||
} | ||
}) | ||
setTimeout(function(){ | ||
if(pos2 === null) return | ||
fail('Not enough situations called') | ||
done() | ||
}, 1200) | ||
}) | ||
}) | ||
describe('once()', function() { | ||
it('adds a callback which is called once at the specified position', function(done) { | ||
fx.start().once(0.5, function(pos, eased){ | ||
expect(pos).toBeGreaterThan(0.49) | ||
done() | ||
}) | ||
}) | ||
}) | ||
it('animates the x/y-attr', function(done) { | ||
fx.move(200,200).after(function(){ | ||
expect(rect.x()).toBe(200) | ||
expect(rect.y()).toBe(200) | ||
done() | ||
}); | ||
setTimeout(function(){ | ||
@@ -30,7 +270,7 @@ expect(rect.x()).toBeGreaterThan(100) | ||
}) | ||
it('animates matrix', function(done) { | ||
fx.transform({a:0.8, b:0.4, c:-0.15, d:0.7, e: 90.3, f: 27.07}).after(function(){ | ||
var ctm = rect.ctm() | ||
@@ -43,9 +283,9 @@ expect(ctm.a).toBeCloseTo(0.8) | ||
expect(ctm.f).toBeCloseTo(27.07) | ||
done() | ||
}) | ||
setTimeout(function(){ | ||
var ctm = rect.ctm(); | ||
@@ -59,5 +299,5 @@ expect(ctm.a).toBeLessThan(1) | ||
}, 250) | ||
}) | ||
}) |
describe('Regex', function() { | ||
describe('matchers', function() { | ||
describe('unit', function() { | ||
describe('numberAndUnit', function() { | ||
var match | ||
it('is true with a positive unit value', function() { | ||
match = ('10%').match(SVG.regex.unit) | ||
match = ('10%').match(SVG.regex.numberAndUnit) | ||
expect(match[1]).toBe('10') | ||
expect(match[2]).toBe('%') | ||
expect(match[5]).toBe('%') | ||
}) | ||
it('is true with a negative unit value', function() { | ||
match = ('-11%').match(SVG.regex.unit) | ||
match = ('-11%').match(SVG.regex.numberAndUnit) | ||
expect(match[1]).toBe('-11') | ||
expect(match[2]).toBe('%') | ||
expect(match[5]).toBe('%') | ||
}) | ||
it('is false with a positive unit value', function() { | ||
match = ('NotAUnit').match(SVG.regex.unit) | ||
match = ('NotAUnit').match(SVG.regex.numberAndUnit) | ||
expect(match).toBeNull() | ||
}) | ||
it('is true with a number', function() { | ||
["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4", "1e+12"].forEach(function(s) { | ||
expect(SVG.regex.numberAndUnit.test(s)).toBeTruthy() | ||
}) | ||
}) | ||
it('is false with a faulty number', function() { | ||
["+-1", "1.2.3", "1+1", "1e4.5", ".5.", "1f5", "."].forEach(function(s) { | ||
expect(SVG.regex.numberAndUnit.test(s)).toBeFalsy() | ||
}) | ||
}) | ||
it('is true with a number with unit', function() { | ||
["1px", "-1em", "+15%", "1.55s", ".5pt", "5.deg", "1.3e2rad", "1E-4grad", "1e+12cm"].forEach(function(s) { | ||
expect(SVG.regex.numberAndUnit.test(s)).toBeTruthy() | ||
}) | ||
}) | ||
it('is false with a faulty number or wrong unit', function() { | ||
["1em1", "-1eq,5"].forEach(function(s) { | ||
expect(SVG.regex.numberAndUnit.test(s)).toBeFalsy() | ||
}) | ||
}) | ||
}) | ||
@@ -49,4 +72,22 @@ }) | ||
describe('isNumber', function() { | ||
it('is true with a number', function() { | ||
["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4", "1e+12"].forEach(function(s) { | ||
expect(SVG.regex.isNumber.test(s)).toBeTruthy() | ||
}) | ||
}) | ||
it('is false with a faulty number', function() { | ||
["1a", "+-1", "1.2.3", "1+1", "1e4.5", ".5.", "1f5", "."].forEach(function(s) { | ||
expect(SVG.regex.isNumber.test(s)).toBeFalsy() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
@@ -7,11 +7,11 @@ // IMPORTANT!!! | ||
var text | ||
beforeEach(function() { | ||
text = draw.text(loremIpsum).size(5) | ||
}) | ||
afterEach(function() { | ||
draw.clear() | ||
}) | ||
describe('x()', function() { | ||
@@ -32,3 +32,3 @@ it('returns the value of x without an argument', function() { | ||
}) | ||
describe('y()', function() { | ||
@@ -51,3 +51,3 @@ it('returns the value of y without an argument', function() { | ||
}) | ||
describe('cx()', function() { | ||
@@ -69,3 +69,3 @@ it('returns the value of cx without an argument', function() { | ||
}) | ||
describe('cy()', function() { | ||
@@ -82,3 +82,3 @@ it('returns the value of cy without an argument', function() { | ||
}) | ||
describe('move()', function() { | ||
@@ -92,3 +92,3 @@ it('sets the x and y position', function() { | ||
}) | ||
describe('center()', function() { | ||
@@ -102,3 +102,3 @@ it('sets the cx and cy position', function() { | ||
}) | ||
describe('size()', function() { | ||
@@ -222,3 +222,3 @@ it('should define the width and height of the element', function() { | ||
}) | ||
describe('build()', function() { | ||
@@ -254,3 +254,16 @@ it('enables adding multiple plain text nodes when given true', function() { | ||
}) | ||
describe('setData()', function() { | ||
it('read all data from the svgjs:data attribute and assign it to el.dom', function(){ | ||
text.attr('svgjs:data', '{"foo":"bar","leading":"3px"}') | ||
text.setData(JSON.parse(text.attr('svgjs:data'))) | ||
expect(text.dom.foo).toBe('bar') | ||
expect(text.dom.leading instanceof SVG.Number).toBeTruthy() | ||
expect(text.dom.leading.value).toBe(3) | ||
expect(text.dom.leading.unit).toBe('px') | ||
}) | ||
}) | ||
}) | ||
@@ -257,0 +270,0 @@ |
@@ -174,3 +174,3 @@ | ||
// loop trough ancestors if type is given | ||
while(parent.node instanceof SVGElement){ | ||
while(parent && parent.node instanceof SVGElement){ | ||
if(typeof type === 'string' ? parent.matches(type) : parent instanceof type) return parent | ||
@@ -251,3 +251,3 @@ parent = SVG.adopt(parent.node.parentNode) | ||
if(Object.keys(this.dom).length) | ||
this.node.setAttributeNS(SVG.svgjs, 'svgjs:data', JSON.stringify(this.dom)) | ||
this.node.setAttribute('svgjs:data', JSON.stringify(this.dom)) // see #428 | ||
@@ -261,3 +261,6 @@ return this | ||
} | ||
, is: function(obj){ | ||
return is(this, obj) | ||
} | ||
} | ||
}) |
@@ -33,2 +33,3 @@ // Add events to elements | ||
SVG.handlerMap = [] | ||
SVG.listenerId = 0 | ||
@@ -49,4 +50,7 @@ // Add event binder in the SVG namespace | ||
if(!listener._svgjsListenerId) | ||
listener._svgjsListenerId = ++SVG.listenerId | ||
// reference listener | ||
SVG.listeners[index][ev][ns][listener] = l | ||
SVG.listeners[index][ev][ns][listener._svgjsListenerId] = l | ||
@@ -64,4 +68,7 @@ // add listener | ||
if(index == -1) return | ||
if (listener) { | ||
if(typeof listener == 'function') listener = listener._svgjsListenerId | ||
if(!listener) return | ||
// remove listener reference | ||
@@ -68,0 +75,0 @@ if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns || '*']) { |
1049
src/fx.js
@@ -0,429 +1,624 @@ | ||
SVG.easing = { | ||
'-': function(pos){return pos} | ||
, '<>':function(pos){return -Math.cos(pos * Math.PI) / 2 + 0.5} | ||
, '>': function(pos){return Math.sin(pos * Math.PI / 2)} | ||
, '<': function(pos){return -Math.cos(pos * Math.PI / 2) + 1} | ||
} | ||
SVG.morph = function(from, to) { | ||
return new MorphObj(from, to).at(pos) | ||
} | ||
SVG.Situation = SVG.invent({ | ||
create: function(o){ | ||
this.init = false | ||
this.reversed = false | ||
this.reversing = false | ||
this.duration = new SVG.Number(o.duration).valueOf() | ||
this.delay = new SVG.Number(o.delay).valueOf() | ||
this.start = +new Date() + this.delay | ||
this.finish = this.start + this.duration | ||
this.ease = o.ease | ||
this.loop = false | ||
this.loops = false | ||
this.animations = { | ||
// functionToCall: [list of morphable objects] | ||
// e.g. move: [SVG.Number, SVG.Number] | ||
} | ||
this.attrs = { | ||
// holds all attributes which are not represented from a function svg.js provides | ||
// e.g. someAttr: SVG.Number | ||
} | ||
this.styles = { | ||
// holds all styles which should be animated | ||
// e.g. fill-color: SVG.Color | ||
} | ||
this.transforms = [ | ||
// holds all transformations as transformation objects | ||
// e.g. [SVG.Rotate, SVG.Translate, SVG.Matrix] | ||
] | ||
this.once = { | ||
// functions to fire at a specific position | ||
// e.g. "0.5": function foo(){} | ||
} | ||
} | ||
}) | ||
SVG.Delay = function(delay){ | ||
this.delay = new SVG.Number(delay).valueOf() | ||
} | ||
SVG.FX = SVG.invent({ | ||
// Initialize FX object | ||
create: function(element) { | ||
// store target element | ||
this.target = element | ||
this._target = element | ||
this.situations = [] | ||
this.active = false | ||
this.situation = null | ||
this.paused = false | ||
this.lastPos = 0 | ||
this.pos = 0 | ||
} | ||
// Add class methods | ||
, extend: { | ||
// Add animation parameters and start animation | ||
animate: function(d, ease, delay) { | ||
var akeys, skeys, key | ||
, element = this.target | ||
, fx = this | ||
// dissect object if one is passed | ||
if (typeof d == 'object') { | ||
delay = d.delay | ||
ease = d.ease | ||
d = d.duration | ||
/** | ||
* sets or returns the target of this animation | ||
* @param o object || number In case of Object it holds all parameters. In case of number its the duration of the animation | ||
* @param ease function || string Function which should be used for easing or easing keyword | ||
* @param delay Number indicating the delay before the animation starts | ||
* @return target || this | ||
*/ | ||
animate: function(o, ease, delay){ | ||
if(typeof o == 'object'){ | ||
ease = o.ease | ||
delay = o.delay | ||
o = o.duration | ||
} | ||
// ensure default duration and easing | ||
d = d == '=' ? d : d == null ? 1000 : new SVG.Number(d).valueOf() | ||
ease = ease || '<>' | ||
var situation = new SVG.Situation({ | ||
duration: o || 1000, | ||
delay: delay || 0, | ||
ease: SVG.easing[ease || '-'] || ease | ||
}) | ||
// process values | ||
fx.at = function(pos) { | ||
var i | ||
this.queue(situation) | ||
// normalise pos | ||
pos = pos < 0 ? 0 : pos > 1 ? 1 : pos | ||
return this | ||
} | ||
// collect attribute keys | ||
if (akeys == null) { | ||
akeys = [] | ||
for (key in fx.attrs) | ||
akeys.push(key) | ||
/** | ||
* sets a delay before the next element of the queue is called | ||
* @param delay Duration of delay in milliseconds | ||
* @return this.target() | ||
*/ | ||
, delay: function(delay){ | ||
var delay = new SVG.Delay(delay) | ||
// make sure morphable elements are scaled, translated and morphed all together | ||
if (element.morphArray && (fx.destination.plot || akeys.indexOf('points') > -1)) { | ||
// get destination | ||
var box | ||
, p = new element.morphArray(fx.destination.plot || fx.attrs.points || element.array()) | ||
return this.queue(delay) | ||
} | ||
// add size | ||
if (fx.destination.size) | ||
p.size(fx.destination.size.width.to, fx.destination.size.height.to) | ||
/** | ||
* sets or returns the target of this animation | ||
* @param null || target SVG.Elemenet which should be set as new target | ||
* @return target || this | ||
*/ | ||
, target: function(target){ | ||
if(target && target instanceof SVG.Element){ | ||
this._target = target | ||
return this | ||
} | ||
// add movement | ||
box = p.bbox() | ||
if (fx.destination.x) | ||
p.move(fx.destination.x.to, box.y) | ||
else if (fx.destination.cx) | ||
p.move(fx.destination.cx.to - box.width / 2, box.y) | ||
return this._target | ||
} | ||
box = p.bbox() | ||
if (fx.destination.y) | ||
p.move(box.x, fx.destination.y.to) | ||
else if (fx.destination.cy) | ||
p.move(box.x, fx.destination.cy.to - box.height / 2) | ||
// returns the position at a given time | ||
, timeToPos: function(timestamp){ | ||
return (timestamp - this.situation.start) / (this.situation.duration) | ||
} | ||
// reset destination values | ||
fx.destination = { | ||
plot: element.array().morph(p) | ||
} | ||
} | ||
} | ||
// returns the timestamp from a given positon | ||
, posToTime: function(pos){ | ||
return this.situation.duration * pos + this.situation.start | ||
} | ||
// collect style keys | ||
if (skeys == null) { | ||
skeys = [] | ||
for (key in fx.styles) | ||
skeys.push(key) | ||
} | ||
// starts the animationloop | ||
, startAnimFrame: function(){ | ||
this.stopAnimFrame() | ||
this.animationFrame = requestAnimationFrame(function(){ this.step() }.bind(this)) | ||
} | ||
// apply easing | ||
pos = ease == '<>' ? | ||
(-Math.cos(pos * Math.PI) / 2) + 0.5 : | ||
ease == '>' ? | ||
Math.sin(pos * Math.PI / 2) : | ||
ease == '<' ? | ||
-Math.cos(pos * Math.PI / 2) + 1 : | ||
ease == '-' ? | ||
pos : | ||
typeof ease == 'function' ? | ||
ease(pos) : | ||
pos | ||
// run plot function | ||
if (fx.destination.plot) { | ||
element.plot(fx.destination.plot.at(pos)) | ||
// cancels the animationframe | ||
, stopAnimFrame: function(){ | ||
cancelAnimationFrame(this.animationFrame) | ||
} | ||
} else { | ||
// run all x-position properties | ||
if (fx.destination.x) | ||
element.x(fx.destination.x.at(pos)) | ||
else if (fx.destination.cx) | ||
element.cx(fx.destination.cx.at(pos)) | ||
// kicks off the animation - only does something when the queue is curretly not active and at least one situation is set | ||
, start: function(){ | ||
// dont start if already started | ||
if(!this.active && this.situation){ | ||
this.situation.start = +new Date + this.situation.delay | ||
this.situation.finish = this.situation.start + this.situation.duration | ||
// run all y-position properties | ||
if (fx.destination.y) | ||
element.y(fx.destination.y.at(pos)) | ||
else if (fx.destination.cy) | ||
element.cy(fx.destination.cy.at(pos)) | ||
this.initAnimations() | ||
this.active = true | ||
this.startAnimFrame() | ||
} | ||
// run all size properties | ||
if (fx.destination.size) | ||
element.size(fx.destination.size.width.at(pos), fx.destination.size.height.at(pos)) | ||
} | ||
return this | ||
} | ||
// run all viewbox properties | ||
if (fx.destination.viewbox) | ||
element.viewbox( | ||
fx.destination.viewbox.x.at(pos) | ||
, fx.destination.viewbox.y.at(pos) | ||
, fx.destination.viewbox.width.at(pos) | ||
, fx.destination.viewbox.height.at(pos) | ||
) | ||
/** | ||
* adds a function / Situation to the animation queue | ||
* @param fn function / situation to add | ||
* @return this | ||
*/ | ||
, queue: function(fn){ | ||
if(typeof fn == 'function' || fn instanceof SVG.Situation || fn instanceof SVG.Delay) | ||
this.situations.push(fn) | ||
// run leading property | ||
if (fx.destination.leading) | ||
element.leading(fx.destination.leading.at(pos)) | ||
if(!this.situation) this.situation = this.situations.shift() | ||
// animate attributes | ||
for (i = akeys.length - 1; i >= 0; i--) | ||
element.attr(akeys[i], at(fx.attrs[akeys[i]], pos)) | ||
return this | ||
} | ||
// animate styles | ||
for (i = skeys.length - 1; i >= 0; i--) | ||
element.style(skeys[i], at(fx.styles[skeys[i]], pos)) | ||
/** | ||
* pulls next element from the queue and execute it | ||
* @return this | ||
*/ | ||
, dequeue: function(){ | ||
// stop current animation | ||
this.situation && this.situation.stop && this.situation.stop() | ||
// callback for each keyframe | ||
if (fx.situation.during) | ||
fx.situation.during.call(element, pos, function(from, to) { | ||
return at({ from: from, to: to }, pos) | ||
}) | ||
// get next animation from queue | ||
this.situation = this.situations.shift() | ||
if(this.situation){ | ||
var fn = function(){ | ||
if(this.situation instanceof SVG.Situation) | ||
this.initAnimations().at(0) | ||
else if(this.situation instanceof SVG.Delay) | ||
this.dequeue() | ||
else | ||
this.situation.call(this) | ||
}.bind(this) | ||
// start next animation | ||
if(this.situation.delay){ | ||
setTimeout(function(){fn()}, this.situation.delay) | ||
}else{ | ||
fn() | ||
} | ||
} | ||
if (typeof d === 'number') { | ||
// delay animation | ||
this.timeout = setTimeout(function() { | ||
var start = new Date().getTime() | ||
// initialize situation object | ||
fx.situation.start = start | ||
fx.situation.play = true | ||
fx.situation.finish = start + d | ||
fx.situation.duration = d | ||
fx.situation.ease = ease | ||
return this | ||
} | ||
// render function | ||
fx.render = function() { | ||
if (fx.situation.play === true) { | ||
// calculate pos | ||
var time = new Date().getTime() | ||
, pos = time > fx.situation.finish ? 1 : (time - fx.situation.start) / d | ||
// updates all animations to the current state of the element | ||
// this is important when one property could be changed from another property | ||
, initAnimations: function() { | ||
var i | ||
var s = this.situation | ||
// reverse pos if animation is reversed | ||
if (fx.situation.reversing) | ||
pos = -pos + 1 | ||
// process values | ||
fx.at(pos) | ||
// finish off animation | ||
if (time > fx.situation.finish) { | ||
if (fx.destination.plot) | ||
element.plot(new SVG.PointArray(fx.destination.plot.destination).settle()) | ||
if(s.init) return this | ||
if (fx.situation.loop === true || (typeof fx.situation.loop == 'number' && fx.situation.loop > 0)) { | ||
// register reverse | ||
if (fx.situation.reverse) | ||
fx.situation.reversing = !fx.situation.reversing | ||
for(i in s.animations){ | ||
if (typeof fx.situation.loop == 'number') { | ||
// reduce loop count | ||
if (!fx.situation.reverse || fx.situation.reversing) | ||
--fx.situation.loop | ||
if(i == 'viewbox'){ | ||
s.animations[i] = this.target().viewbox().morph(s.animations[i]) | ||
}else{ | ||
// remove last loop if reverse is disabled | ||
if (!fx.situation.reverse && fx.situation.loop == 1) | ||
--fx.situation.loop | ||
} | ||
fx.animate(d, ease, delay) | ||
} else { | ||
fx.situation.after ? fx.situation.after.apply(element, [fx]) : fx.stop() | ||
} | ||
// TODO: this is not a clean clone of the array. We may have some unchecked references | ||
s.animations[i].value = (i == 'plot' ? this.target().array().value : this.target()[i]()) | ||
} else { | ||
fx.animationFrame = requestAnimationFrame(fx.render) | ||
} | ||
} else { | ||
fx.animationFrame = requestAnimationFrame(fx.render) | ||
} | ||
// sometimes we get back an object and not the real value, fix this | ||
if(s.animations[i].value.value){ | ||
s.animations[i].value = s.animations[i].value.value | ||
} | ||
// start animation | ||
fx.render() | ||
}, new SVG.Number(delay).valueOf()) | ||
if(s.animations[i].relative) | ||
s.animations[i].destination.value = s.animations[i].destination.value + s.animations[i].value | ||
} | ||
} | ||
for(i in s.attrs){ | ||
if(s.attrs[i] instanceof SVG.Color){ | ||
var color = new SVG.Color(this.target().attr(i)) | ||
s.attrs[i].r = color.r | ||
s.attrs[i].g = color.g | ||
s.attrs[i].b = color.b | ||
}else{ | ||
s.attrs[i].value = this.target().attr(i)// + s.attrs[i].value | ||
} | ||
} | ||
for(i in s.styles){ | ||
s.styles[i].value = this.target().style(i) | ||
} | ||
s.initialTransformation = this.target().matrixify() | ||
s.init = true | ||
return this | ||
} | ||
// Get bounding box of target element | ||
, bbox: function() { | ||
return this.target.bbox() | ||
, clearQueue: function(){ | ||
this.situations = [] | ||
return this | ||
} | ||
// Add animatable attributes | ||
, attr: function(a, v) { | ||
// apply attributes individually | ||
if (typeof a == 'object') { | ||
for (var key in a) | ||
this.attr(key, a[key]) | ||
} else { | ||
// get the current state | ||
var from = this.target.attr(a) | ||
, clearCurrent: function(){ | ||
this.situation = null | ||
return this | ||
} | ||
/** stops the animation immediately | ||
* @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. | ||
* @param clearQueue A Boolean indicating whether to remove queued animation as well. | ||
* @return this | ||
*/ | ||
, stop: function(jumpToEnd, clearQueue){ | ||
if(!this.active) this.start() | ||
// detect format | ||
if (a == 'transform') { | ||
// merge given transformation with an existing one | ||
if (this.attrs[a]) | ||
v = this.attrs[a].destination.multiply(v) | ||
if(clearQueue){ | ||
this.clearQueue() | ||
} | ||
// prepare matrix for morphing | ||
this.attrs[a] = (new SVG.Matrix(this.target)).morph(v) | ||
this.active = false | ||
// add parametric rotation values | ||
if (this.param) { | ||
// get initial rotation | ||
v = this.target.transform('rotation') | ||
if(jumpToEnd){ | ||
// add param | ||
this.attrs[a].param = { | ||
from: this.target.param || { rotation: v, cx: this.param.cx, cy: this.param.cy } | ||
, to: this.param | ||
} | ||
} | ||
this.situation.loop = false | ||
} else { | ||
this.attrs[a] = SVG.Color.isColor(v) ? | ||
// prepare color for morphing | ||
new SVG.Color(from).morph(v) : | ||
SVG.regex.unit.test(v) ? | ||
// prepare number for morphing | ||
new SVG.Number(from).morph(v) : | ||
// prepare for plain morphing | ||
{ from: from, to: v } | ||
if(this.situation.loops % 2 == 0 && this.situation.reversing){ | ||
this.situation.reversed = true | ||
} | ||
this.at(1) | ||
} | ||
return this | ||
this.stopAnimFrame() | ||
clearTimeout(this.timeout) | ||
return this.clearCurrent() | ||
} | ||
// Add animatable styles | ||
, style: function(s, v) { | ||
if (typeof s == 'object') | ||
for (var key in s) | ||
this.style(key, s[key]) | ||
else | ||
this.styles[s] = { from: this.target.style(s), to: v } | ||
/** resets the element to the state where the current element has started | ||
* @return this | ||
*/ | ||
, reset: function(){ | ||
if(this.situation){ | ||
var temp = this.situation | ||
this.stop() | ||
this.situation = temp | ||
this.at(0) | ||
} | ||
return this | ||
} | ||
// Animatable x-axis | ||
, x: function(x) { | ||
this.destination.x = new SVG.Number(this.target.x()).morph(x) | ||
// Stop the currently-running animation, remove all queued animations, and complete all animations for the element. | ||
, finish: function(){ | ||
this.stop(true, false) | ||
while(this.dequeue().situation && this.stop(true, false)); | ||
this.clearQueue().clearCurrent() | ||
return this | ||
} | ||
// Animatable y-axis | ||
, y: function(y) { | ||
this.destination.y = new SVG.Number(this.target.y()).morph(y) | ||
return this | ||
// set the internal animation pointer to the specified position and updates the visualisation | ||
, at: function(pos){ | ||
this.pos = pos | ||
this.situation.start = +new Date - pos * this.situation.duration | ||
this.situation.finish = this.situation.start + this.situation.duration | ||
return this.step(true) | ||
} | ||
// Animatable center x-axis | ||
, cx: function(x) { | ||
this.destination.cx = new SVG.Number(this.target.cx()).morph(x) | ||
// speeds up the animation by the given factor | ||
// this changes the duration of the animation | ||
, speed: function(speed){ | ||
this.situation.duration = this.situation.duration * this.pos + (1-this.pos) * this.situation.duration / speed | ||
this.situation.finish = this.situation.start + this.situation.duration | ||
return this.at(this.pos) | ||
} | ||
// Make loopable | ||
, loop: function(times, reverse) { | ||
// store current loop and total loops | ||
this.situation.loop = this.situation.loops = times || true | ||
if(reverse) this.last().reversing = true | ||
return this | ||
} | ||
// Animatable center y-axis | ||
, cy: function(y) { | ||
this.destination.cy = new SVG.Number(this.target.cy()).morph(y) | ||
// pauses the animation | ||
, pause: function(){ | ||
this.paused = true | ||
this.stopAnimFrame() | ||
clearTimeout(this.timeout) | ||
return this | ||
} | ||
// Add animatable move | ||
, move: function(x, y) { | ||
return this.x(x).y(y) | ||
// unpause the animation | ||
, play: function(){ | ||
if(!this.paused) return this | ||
this.paused = false | ||
return this.at(this.pos) | ||
} | ||
// Add animatable center | ||
, center: function(x, y) { | ||
return this.cx(x).cy(y) | ||
} | ||
// Add animatable size | ||
, size: function(width, height) { | ||
if (this.target instanceof SVG.Text) { | ||
// animate font size for Text elements | ||
this.attr('font-size', width) | ||
} else { | ||
// animate bbox based size for all other elements | ||
var box = this.target.bbox() | ||
this.destination.size = { | ||
width: new SVG.Number(box.width).morph(width) | ||
, height: new SVG.Number(box.height).morph(height) | ||
} | ||
} | ||
/** | ||
* toggle or set the direction of the animation | ||
* true sets direction to backwards while false sets it to forwards | ||
* @param reversed Boolean indicating whether to reverse the animation or not (default: toggle the reverse status) | ||
* @return this | ||
*/ | ||
, reverse: function(reversed){ | ||
var c = this.last() | ||
if(typeof reversed == 'undefined') c.reversed = !c.reversed | ||
else c.reversed = reversed | ||
return this | ||
} | ||
// Add animatable plot | ||
, plot: function(p) { | ||
this.destination.plot = p | ||
return this | ||
/** | ||
* returns a float from 0-1 indicating the progress of the current animation | ||
* @param eased Boolean indicating whether the returned position should be eased or not | ||
* @return number | ||
*/ | ||
, progress: function(easeIt){ | ||
return easeIt ? this.situation.ease(this.pos) : this.pos | ||
} | ||
// Add leading method | ||
, leading: function(value) { | ||
if (this.target.destination.leading) | ||
this.destination.leading = new SVG.Number(this.target.destination.leading).morph(value) | ||
/** | ||
* adds a callback function which is called when the current animation is finished | ||
* @param fn Function which should be executed as callback | ||
* @return number | ||
*/ | ||
, after: function(fn){ | ||
var c = this.last() | ||
, wrapper = function wrapper(e){ | ||
if(e.detail.situation == c){ | ||
fn.call(this, c) | ||
this.off('finished.fx', wrapper) // prevent memory leak | ||
} | ||
} | ||
this.target().on('finished.fx', wrapper) | ||
return this | ||
} | ||
// Add animatable viewbox | ||
, viewbox: function(x, y, width, height) { | ||
if (this.target instanceof SVG.Container) { | ||
var box = this.target.viewbox() | ||
this.destination.viewbox = { | ||
x: new SVG.Number(box.x).morph(x) | ||
, y: new SVG.Number(box.y).morph(y) | ||
, width: new SVG.Number(box.width).morph(width) | ||
, height: new SVG.Number(box.height).morph(height) | ||
} | ||
} | ||
return this | ||
// adds a callback which is called whenever one animation step is performed | ||
, during: function(fn){ | ||
var c = this.last() | ||
, wrapper = function(e){ | ||
if(e.detail.situation == c){ | ||
fn.call(this, e.detail.pos, SVG.morph, e.detail.eased, c) | ||
} | ||
} | ||
// see above | ||
this.target().off('during.fx', wrapper).on('during.fx', wrapper) | ||
return this.after(function(){ | ||
this.off('during.fx', wrapper) | ||
}) | ||
} | ||
// Add animateable gradient update | ||
, update: function(o) { | ||
if (this.target instanceof SVG.Stop) { | ||
if (o.opacity != null) this.attr('stop-opacity', o.opacity) | ||
if (o.color != null) this.attr('stop-color', o.color) | ||
if (o.offset != null) this.attr('offset', new SVG.Number(o.offset)) | ||
} | ||
// calls after ALL animations in the queue are finished | ||
, afterAll: function(fn){ | ||
var wrapper = function wrapper(e){ | ||
fn.call(this) | ||
this.off('allfinished.fx', wrapper) | ||
} | ||
// see above | ||
this.target().off('allfinished.fx', wrapper).on('allfinished.fx', wrapper) | ||
return this | ||
} | ||
// Add callback for each keyframe | ||
, during: function(during) { | ||
this.situation.during = during | ||
return this | ||
// calls on every animation step for all animations | ||
, duringAll: function(fn){ | ||
var wrapper = function(e){ | ||
fn.call(this, e.detail.pos, SVG.morph, e.detail.eased, e.detail.situation) | ||
} | ||
this.target().off('during.fx', wrapper).on('during.fx', wrapper) | ||
return this.afterAll(function(){ | ||
this.off('during.fx', wrapper) | ||
}) | ||
} | ||
// Callback after animation | ||
, after: function(after) { | ||
this.situation.after = after | ||
return this | ||
, last: function(){ | ||
return this.situations.length ? this.situations[this.situations.length-1] : this.situation | ||
} | ||
// Make loopable | ||
, loop: function(times, reverse) { | ||
// store current loop and total loops | ||
this.situation.loop = this.situation.loops = times || true | ||
// make reversable | ||
this.situation.reverse = !!reverse | ||
// adds one property to the animations | ||
, add: function(method, args, type){ | ||
this.last()[type || 'animations'][method] = args | ||
setTimeout(function(){this.start()}.bind(this), 0) | ||
return this | ||
} | ||
// Stop running animation | ||
, stop: function(fulfill) { | ||
// fulfill animation | ||
if (fulfill === true) { | ||
this.animate(0) | ||
/** perform one step of the animation | ||
* @param ignoreTime Boolean indicating whether to ignore time and use position directly or recalculate position based on time | ||
* @return this | ||
*/ | ||
, step: function(ignoreTime){ | ||
if (this.situation.after) | ||
this.situation.after.apply(this.target, [this]) | ||
// convert current time to position | ||
if(!ignoreTime) this.pos = this.timeToPos(+new Date) | ||
} else { | ||
// stop current animation | ||
clearTimeout(this.timeout) | ||
cancelAnimationFrame(this.animationFrame); | ||
if(this.pos >= 1 && (this.situation.loop === true || (typeof this.situation.loop == 'number' && --this.situation.loop))){ | ||
// reset storage for properties | ||
this.attrs = {} | ||
this.styles = {} | ||
this.situation = {} | ||
this.destination = {} | ||
if(this.situation.reversing){ | ||
this.situation.reversed = !this.situation.reversed | ||
} | ||
return this.at(this.pos-1) | ||
} | ||
if(this.situation.reversed) this.pos = 1 - this.pos | ||
// correct position | ||
if(this.pos > 1)this.pos = 1 | ||
if(this.pos < 0)this.pos = 0 | ||
// apply easing | ||
var eased = this.situation.ease(this.pos) | ||
// call once-callbacks | ||
for(var i in this.situation.once){ | ||
if(i > this.lastPos && i <= eased){ | ||
this.situation.once[i].call(this.target(), this.pos, eased) | ||
delete this.situation.once[i] | ||
} | ||
} | ||
// fire during callback with position, eased position and current situation as parameter | ||
if(this.active) this.target().fire('during', {pos: this.pos, eased: eased, fx: this, situation: this.situation}) | ||
// the user may call stop or finish in the during callback | ||
// so make sure that we still have a valid situation | ||
if(!this.situation){ | ||
return this | ||
} | ||
// apply the actual animation to every property | ||
this.eachAt() | ||
// do final code when situation is finished | ||
if((this.pos == 1 && !this.situation.reversed) || (this.situation.reversed && this.pos == 0)){ | ||
// stop animation callback | ||
this.stopAnimFrame() | ||
// fire finished callback with current situation as parameter | ||
this.target().fire('finished', {fx:this, situation: this.situation}) | ||
if(!this.situations.length){ | ||
this.target().fire('allfinished') | ||
this.target().off('.fx') // there shouldnt be any binding left, but to make sure... | ||
this.active = false | ||
} | ||
// start next animation | ||
if(this.active) this.dequeue() | ||
else this.clearCurrent() | ||
}else if(!this.paused && this.active){ | ||
// we continue animating when we are not at the end | ||
this.startAnimFrame() | ||
} | ||
// save last eased position for once callback triggering | ||
this.lastPos = eased | ||
return this | ||
} | ||
// Pause running animation | ||
, pause: function() { | ||
if (this.situation.play === true) { | ||
this.situation.play = false | ||
this.situation.pause = new Date().getTime() | ||
// calculates the step for every property and calls block with it | ||
, eachAt: function(){ | ||
var i, at, self = this, target = this.target(), s = this.situation | ||
// apply animations which can be called trough a method | ||
for(i in s.animations){ | ||
at = [].concat(s.animations[i]).map(function(el){ | ||
return el.at ? el.at(s.ease(self.pos), self.pos) : el | ||
}) | ||
target[i].apply(target, at) | ||
} | ||
// apply animation which has to be applied with attr() | ||
for(i in s.attrs){ | ||
at = [i].concat(s.attrs[i]).map(function(el){ | ||
return el.at ? el.at(s.ease(self.pos), self.pos) : el | ||
}) | ||
target.attr.apply(target, at) | ||
} | ||
// apply animation which has to be applied with style() | ||
for(i in s.styles){ | ||
at = [i].concat(s.styles[i]).map(function(el){ | ||
return el.at ? el.at(s.ease(self.pos), self.pos) : el | ||
}) | ||
target.style.apply(target, at) | ||
} | ||
// animate initialTransformation which has to be chained | ||
if(s.transforms.length){ | ||
// get inital initialTransformation | ||
at = s.initialTransformation | ||
for(i in s.transforms){ | ||
// get next transformation in chain | ||
var a = s.transforms[i] | ||
// multiply matrix directly | ||
if(a instanceof SVG.Matrix){ | ||
if(a.relative){ | ||
at = at.multiply(a.at(s.ease(this.pos))) | ||
}else{ | ||
at = at.morph(a).at(s.ease(this.pos)) | ||
} | ||
continue | ||
} | ||
// when transformation is absolute we have to reset the needed transformation first | ||
if(!a.relative) | ||
a.undo(at.extract()) | ||
// and reapply it after | ||
at = at.multiply(a.at(s.ease(this.pos))) | ||
} | ||
// set new matrix on element | ||
target.matrix(at) | ||
} | ||
return this | ||
} | ||
// Play running animation | ||
, play: function() { | ||
if (this.situation.play === false) { | ||
var pause = new Date().getTime() - this.situation.pause | ||
this.situation.finish += pause | ||
this.situation.start += pause | ||
this.situation.play = true | ||
} | ||
// adds an once-callback which is called at a specific position and never again | ||
, once: function(pos, fn, isEased){ | ||
if(!isEased)pos = this.situation.ease(pos) | ||
this.situation.once[pos] = fn | ||
return this | ||
} | ||
} | ||
// Define parent class | ||
, parent: SVG.Element | ||
@@ -434,12 +629,20 @@ | ||
// Get fx module or create a new one, then animate with given duration and ease | ||
animate: function(d, ease, delay) { | ||
return (this.fx || (this.fx = new SVG.FX(this))).stop().animate(d, ease, delay) | ||
animate: function(o, ease, delay) { | ||
return (this.fx || (this.fx = new SVG.FX(this))).animate(o, ease, delay) | ||
} | ||
// Stop current animation; this is an alias to the fx instance | ||
, stop: function(fulfill) { | ||
, delay: function(delay){ | ||
return (this.fx || (this.fx = new SVG.FX(this))).delay(delay) | ||
} | ||
, stop: function(jumpToEnd, clearQueue) { | ||
if (this.fx) | ||
this.fx.stop(fulfill) | ||
this.fx.stop(jumpToEnd, clearQueue) | ||
return this | ||
} | ||
, finish: function() { | ||
if (this.fx) | ||
this.fx.finish() | ||
return this | ||
} | ||
// Pause current animation | ||
@@ -459,4 +662,160 @@ , pause: function() { | ||
} | ||
} | ||
}) | ||
// MorphObj is used whenever no morphable object is given | ||
SVG.MorphObj = SVG.invent({ | ||
create: function(from, to){ | ||
// prepare color for morphing | ||
if(SVG.Color.isColor(to)) return new SVG.Color(from).morph(to) | ||
// prepare number for morphing | ||
if(SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to) | ||
// prepare for plain morphing | ||
this.value = 0 | ||
this.destination = to | ||
} | ||
, extend: { | ||
at: function(pos, real){ | ||
return real < 1 ? this.value : this.destination | ||
}, | ||
valueOf: function(){ | ||
return this.value | ||
} | ||
} | ||
}) | ||
SVG.extend(SVG.FX, { | ||
// Add animatable attributes | ||
attr: function(a, v, relative) { | ||
// apply attributes individually | ||
if (typeof a == 'object') { | ||
for (var key in a) | ||
this.attr(key, a[key]) | ||
} else { | ||
// the MorphObj takes care about the right function used | ||
this.add(a, new SVG.MorphObj(null, v), 'attrs') | ||
} | ||
return this | ||
} | ||
// Add animatable styles | ||
, style: function(s, v) { | ||
if (typeof s == 'object') | ||
for (var key in s) | ||
this.style(key, s[key]) | ||
else | ||
this.add(s, new SVG.MorphObj(null, v), 'styles') | ||
return this | ||
} | ||
// Animatable x-axis | ||
, x: function(x, relative) { | ||
if(this.target() instanceof SVG.G){ | ||
this.transform({x:x}, relative) | ||
return this | ||
} | ||
var num = new SVG.Number().morph(x) | ||
num.relative = relative | ||
return this.add('x', num) | ||
} | ||
// Animatable y-axis | ||
, y: function(y, relative) { | ||
if(this.target() instanceof SVG.G){ | ||
this.transform({y:y}, relative) | ||
return this | ||
} | ||
var num = new SVG.Number().morph(y) | ||
num.relative = relative | ||
return this.add('y', num) | ||
} | ||
// Animatable center x-axis | ||
, cx: function(x) { | ||
return this.add('cx', new SVG.Number().morph(x)) | ||
} | ||
// Animatable center y-axis | ||
, cy: function(y) { | ||
return this.add('cy', new SVG.Number().morph(y)) | ||
} | ||
// Add animatable move | ||
, move: function(x, y) { | ||
return this.x(x).y(y) | ||
} | ||
// Add animatable center | ||
, center: function(x, y) { | ||
return this.cx(x).cy(y) | ||
} | ||
// Add animatable size | ||
, size: function(width, height) { | ||
if (this.target() instanceof SVG.Text) { | ||
// animate font size for Text elements | ||
this.attr('font-size', width) | ||
} else { | ||
// animate bbox based size for all other elements | ||
var box | ||
if(!width || !height){ | ||
box = this.target().bbox() | ||
} | ||
if(!width){ | ||
width = box.width / box.height * height | ||
} | ||
if(!height){ | ||
height = box.height / box.width * width | ||
} | ||
this.add('width' , new SVG.Number().morph(width)) | ||
.add('height', new SVG.Number().morph(height)) | ||
} | ||
return this | ||
} | ||
// Add animatable plot | ||
, plot: function(p) { | ||
return this.add('plot', this.target().array().morph(p)) | ||
} | ||
// Add leading method | ||
, leading: function(value) { | ||
return this.target().leading ? | ||
this.add('leading', new SVG.Number().morph(value)) : | ||
this | ||
} | ||
// Add animatable viewbox | ||
, viewbox: function(x, y, width, height) { | ||
if (this.target() instanceof SVG.Container) { | ||
this.add('viewbox', new SVG.ViewBox(x, y, width, height)) | ||
} | ||
return this | ||
} | ||
, update: function(o) { | ||
if (this.target() instanceof SVG.Stop) { | ||
if (typeof o == 'number' || o instanceof SVG.Number) { | ||
return this.update({ | ||
offset: arguments[0] | ||
, color: arguments[1] | ||
, opacity: arguments[2] | ||
}) | ||
} | ||
if (o.opacity != null) this.attr('stop-opacity', o.opacity) | ||
if (o.color != null) this.attr('stop-color', o.color) | ||
if (o.offset != null) this.attr('offset', o.offset) | ||
} | ||
return this | ||
} | ||
}) |
@@ -20,7 +20,7 @@ SVG.G = SVG.invent({ | ||
, cx: function(x) { | ||
return x == null ? this.tbox().cx : this.x(x - this.tbox().width / 2) | ||
return x == null ? this.gbox().cx : this.x(x - this.gbox().width / 2) | ||
} | ||
// Move by center over y-axis | ||
, cy: function(y) { | ||
return y == null ? this.tbox().cy : this.y(y - this.tbox().height / 2) | ||
return y == null ? this.gbox().cy : this.y(y - this.gbox().height / 2) | ||
} | ||
@@ -27,0 +27,0 @@ , gbox: function() { |
@@ -0,1 +1,5 @@ | ||
function is(el, obj){ | ||
return el instanceof obj | ||
} | ||
// tests if a given selector matches an element | ||
@@ -2,0 +6,0 @@ function matches(el, selector) { |
@@ -17,3 +17,3 @@ SVG.Matrix = SVG.invent({ | ||
// merge source | ||
for (i = abcdef.length - 1; i >= 0; i--) | ||
for (i = abcdef.length - 1; i >= 0; --i) | ||
this[abcdef[i]] = source && typeof source[abcdef[i]] === 'number' ? | ||
@@ -36,2 +36,4 @@ source[abcdef[i]] : base[abcdef[i]] | ||
, y: this.f | ||
, transformedX:(this.e * Math.cos(skewX * Math.PI / 180) + this.f * Math.sin(skewX * Math.PI / 180)) / Math.sqrt(this.a * this.a + this.b * this.b) | ||
, transformedY:(this.f * Math.cos(skewX * Math.PI / 180) + this.e * Math.sin(-skewX * Math.PI / 180)) / Math.sqrt(this.c * this.c + this.d * this.d) | ||
// skew | ||
@@ -51,2 +53,3 @@ , skewX: -skewX | ||
, f: this.f | ||
, matrix: new SVG.Matrix(this) | ||
} | ||
@@ -189,2 +192,2 @@ } | ||
}) | ||
}) |
@@ -15,3 +15,3 @@ // Module for unit convertions | ||
} else if (typeof value === 'string') { | ||
unit = value.match(SVG.regex.unit) | ||
unit = value.match(SVG.regex.numberAndUnit) | ||
@@ -21,11 +21,11 @@ if (unit) { | ||
this.value = parseFloat(unit[1]) | ||
// normalize | ||
if (unit[2] == '%') | ||
if (unit[5] == '%') | ||
this.value /= 100 | ||
else if (unit[2] == 's') | ||
else if (unit[5] == 's') | ||
this.value *= 1000 | ||
// store unit | ||
this.unit = unit[2] | ||
this.unit = unit[5] | ||
} | ||
@@ -53,2 +53,5 @@ | ||
} | ||
, toJSON: function() { | ||
return this.toString() | ||
} | ||
, // Convert to primitive | ||
@@ -77,3 +80,3 @@ valueOf: function() { | ||
var number = new SVG.Number(this) | ||
if (typeof unit === 'string') | ||
@@ -80,0 +83,0 @@ number.unit = unit |
// Storage for regular expressions | ||
SVG.regex = { | ||
// Parse unit value | ||
unit: /^(-?[\d\.]+)([a-z%]{0,2})$/ | ||
numberAndUnit: /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i | ||
@@ -37,3 +37,3 @@ // Parse hex value | ||
// Test for numeric string | ||
, isNumber: /^-?[\d\.]+$/ | ||
, isNumber: /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i | ||
@@ -68,2 +68,2 @@ // Test for percent value | ||
, X: /X/g | ||
} | ||
} |
@@ -64,7 +64,7 @@ // Define list of available attributes for stroke and fill | ||
, dx: function(x) { | ||
return this.x((this.target || this).x() + x) | ||
return this.x((this instanceof SVG.FX ? 0 : this.x()) + x, true) | ||
} | ||
// Relative move over y axis | ||
, dy: function(y) { | ||
return this.y((this.target || this).y() + y) | ||
return this.y((this instanceof SVG.FX ? 0 : this.y()) + y, true) | ||
} | ||
@@ -71,0 +71,0 @@ // Relative move over x and y axes |
@@ -115,4 +115,6 @@ SVG.Text = SVG.invent({ | ||
, lines: function() { | ||
var node = (this.textPath && this.textPath() || this).node | ||
// filter tspans and map them to SVG.js instances | ||
var lines = SVG.utils.map(SVG.utils.filterSVGElements(this.node.childNodes), function(el){ | ||
var lines = SVG.utils.map(SVG.utils.filterSVGElements(node.childNodes), function(el){ | ||
return SVG.adopt(el) | ||
@@ -163,3 +165,3 @@ }) | ||
this.dom = o | ||
this.dom.leading = o.leading ? new SVG.Number(o.leading.value, o.leading.unit) : new SVG.Number(1.3) | ||
this.dom.leading = new SVG.Number(o.leading || 1.3) | ||
return this | ||
@@ -166,0 +168,0 @@ } |
@@ -6,3 +6,3 @@ SVG.TextPath = SVG.invent({ | ||
// Inherit from | ||
, inherit: SVG.Element | ||
, inherit: SVG.Parent | ||
@@ -9,0 +9,0 @@ // Define parent class |
@@ -1,6 +0,6 @@ | ||
SVG.extend(SVG.Element, SVG.FX, { | ||
SVG.extend(SVG.Element, { | ||
// Add transformations | ||
transform: function(o, relative) { | ||
// get target in case of the fx module, otherwise reference this | ||
var target = this.target || this | ||
var target = this | ||
, matrix | ||
@@ -13,9 +13,2 @@ | ||
// add parametric rotation | ||
if (typeof this.param === 'object') { | ||
matrix.rotation = this.param.rotation | ||
matrix.cx = this.param.cx | ||
matrix.cy = this.param.cy | ||
} | ||
return typeof o === 'string' ? matrix[o] : matrix | ||
@@ -25,5 +18,3 @@ } | ||
// get current matrix | ||
matrix = this instanceof SVG.FX && this.attrs.transform ? | ||
this.attrs.transform : | ||
new SVG.Matrix(target) | ||
matrix = new SVG.Matrix(target) | ||
@@ -46,20 +37,8 @@ // ensure relative flag | ||
// relativize rotation value | ||
if (relative) { | ||
o.rotation += this.param && this.param.rotation != null ? | ||
this.param.rotation : | ||
matrix.extract().rotation | ||
} | ||
// store parametric values | ||
this.param = o | ||
// apply transformation | ||
if (this instanceof SVG.Element) { | ||
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 ? | ||
// relative | ||
matrix.rotate(o.rotation, o.cx, o.cy) : | ||
// absolute | ||
matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy) | ||
@@ -120,6 +99,81 @@ // act on scale | ||
return this.attr(this instanceof SVG.Pattern ? 'patternTransform' : this instanceof SVG.Gradient ? 'gradientTransform' : 'transform', matrix) | ||
return this.attr('transform', matrix) | ||
} | ||
}) | ||
SVG.extend(SVG.FX, { | ||
transform: function(o, relative) { | ||
// get target in case of the fx module, otherwise reference this | ||
var target = this.target() | ||
, matrix | ||
// act as a getter | ||
if (typeof o !== 'object') { | ||
// get current matrix | ||
matrix = new SVG.Matrix(target).extract() | ||
return typeof o === 'string' ? matrix[o] : matrix | ||
} | ||
// ensure relative flag | ||
relative = !!relative || !!o.relative | ||
// act on matrix | ||
if (o.a != null) { | ||
matrix = new SVG.Matrix(o) | ||
// act on rotation | ||
} else if (o.rotation != null) { | ||
// ensure centre point | ||
ensureCentre(o, target) | ||
// apply transformation | ||
matrix = new SVG.Rotate(o.rotation, o.cx, o.cy) | ||
// act on scale | ||
} else if (o.scale != null || o.scaleX != null || o.scaleY != null) { | ||
// ensure centre point | ||
ensureCentre(o, target) | ||
// ensure scale values on both axes | ||
o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1 | ||
o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1 | ||
matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy) | ||
// act on skew | ||
} else if (o.skewX != null || o.skewY != null) { | ||
// ensure centre point | ||
ensureCentre(o, target) | ||
// ensure skew values on both axes | ||
o.skewX = o.skewX != null ? o.skewX : 0 | ||
o.skewY = o.skewY != null ? o.skewY : 0 | ||
matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy) | ||
// act on flip | ||
} else if (o.flip) { | ||
matrix = new SVG.Matrix().morph(new SVG.Matrix().flip( | ||
o.flip | ||
, o.offset == null ? target.bbox()['c' + o.flip] : o.offset | ||
)) | ||
// act on translate | ||
} else if (o.x != null || o.y != null) { | ||
matrix = new SVG.Translate(o.x, o.y) | ||
} | ||
if(!matrix) return this | ||
matrix.relative = relative | ||
this.last().transforms.push(matrix) | ||
setTimeout(function(){this.start()}.bind(this), 0) | ||
return this | ||
} | ||
}) | ||
SVG.extend(SVG.Element, { | ||
@@ -168,1 +222,131 @@ // Reset all transformations | ||
}) | ||
SVG.Transformation = SVG.invent({ | ||
create: function(source, inversed){ | ||
if(arguments.length > 1 && typeof inversed != 'boolean'){ | ||
return this.create([].slice.call(arguments)) | ||
} | ||
if(typeof source == 'object'){ | ||
for(var i = 0, len = this.arguments.length; i < len; ++i){ | ||
this[this.arguments[i]] = source[this.arguments[i]] | ||
} | ||
} | ||
if(Array.isArray(source)){ | ||
for(var i = 0, len = this.arguments.length; i < len; ++i){ | ||
this[this.arguments[i]] = source[i] | ||
} | ||
} | ||
this.inversed = false | ||
if(inversed === true){ | ||
this.inversed = true | ||
} | ||
} | ||
, extend: { | ||
at: function(pos){ | ||
var params = [] | ||
for(var i = 0, len = this.arguments.length; i < len; ++i){ | ||
params.push(this[this.arguments[i]]) | ||
} | ||
var m = this._undo || new SVG.Matrix() | ||
m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos) | ||
return this.inversed ? m.inverse() : m | ||
} | ||
, undo: function(o){ | ||
this._undo = new SVG[capitalize(this.method)](o, true).at(1) | ||
return this | ||
} | ||
} | ||
}) | ||
SVG.Translate = SVG.invent({ | ||
parent: SVG.Matrix | ||
, inherit: SVG.Transformation | ||
, create: function(source, inversed){ | ||
if(typeof source == 'object') this.constructor.call(this, source, inversed) | ||
else this.constructor.call(this, [].slice.call(arguments)) | ||
} | ||
, extend: { | ||
arguments: ['transformedX', 'transformedY'] | ||
, method: 'translate' | ||
} | ||
}) | ||
SVG.Rotate = SVG.invent({ | ||
parent: SVG.Matrix | ||
, inherit: SVG.Transformation | ||
, create: function(source, inversed){ | ||
if(typeof source == 'object') this.constructor.call(this, source, inversed) | ||
else this.constructor.call(this, [].slice.call(arguments)) | ||
} | ||
, extend: { | ||
arguments: ['rotation', 'cx', 'cy'] | ||
, method: 'rotate' | ||
, at: function(pos){ | ||
var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy) | ||
return this.inversed ? m.inverse() : m | ||
} | ||
, undo: function(o){ | ||
this._undo = o | ||
} | ||
} | ||
}) | ||
SVG.Scale = SVG.invent({ | ||
parent: SVG.Matrix | ||
, inherit: SVG.Transformation | ||
, create: function(source, inversed){ | ||
if(typeof source == 'object') this.constructor.call(this, source, inversed) | ||
else this.constructor.call(this, [].slice.call(arguments)) | ||
} | ||
, extend: { | ||
arguments: ['scaleX', 'scaleY', 'cx', 'cy'] | ||
, method: 'scale' | ||
} | ||
}) | ||
SVG.Skew = SVG.invent({ | ||
parent: SVG.Matrix | ||
, inherit: SVG.Transformation | ||
, create: function(source, inversed){ | ||
if(typeof source == 'object') this.constructor.call(this, source, inversed) | ||
else this.constructor.call(this, [].slice.call(arguments)) | ||
} | ||
, extend: { | ||
arguments: ['skewX', 'skewY', 'cx', 'cy'] | ||
, method: 'skew' | ||
} | ||
}) |
SVG.ViewBox = function(element) { | ||
var x, y, width, height | ||
, wm = 1 // width multiplier | ||
, hm = 1 // height multiplier | ||
, box = element.bbox() | ||
, view = (element.attr('viewBox') || '').match(/-?[\d\.]+/g) | ||
, we = element | ||
, he = element | ||
SVG.ViewBox = SVG.invent({ | ||
// get dimensions of current node | ||
width = new SVG.Number(element.width()) | ||
height = new SVG.Number(element.height()) | ||
create: function(source) { | ||
var i, base = [1, 0, 0, 1] | ||
// find nearest non-percentual dimensions | ||
while (width.unit == '%') { | ||
wm *= width.value | ||
width = new SVG.Number(we instanceof SVG.Doc ? we.parent().offsetWidth : we.parent().width()) | ||
we = we.parent() | ||
var x, y, width, height, box, view, we, he | ||
, wm = 1 // width multiplier | ||
, hm = 1 // height multiplier | ||
, reg = /-?[\d\.]+/g | ||
if(source instanceof SVG.Element){ | ||
we = source | ||
he = source | ||
view = (source.attr('viewBox') || '').match(reg) | ||
box = source.bbox | ||
// get dimensions of current node | ||
width = new SVG.Number(source.width()) | ||
height = new SVG.Number(source.height()) | ||
// find nearest non-percentual dimensions | ||
while (width.unit == '%') { | ||
wm *= width.value | ||
width = new SVG.Number(we instanceof SVG.Doc ? we.parent().offsetWidth : we.parent().width()) | ||
we = we.parent() | ||
} | ||
while (height.unit == '%') { | ||
hm *= height.value | ||
height = new SVG.Number(he instanceof SVG.Doc ? he.parent().offsetHeight : he.parent().height()) | ||
he = he.parent() | ||
} | ||
// ensure defaults | ||
this.x = 0 | ||
this.y = 0 | ||
this.width = width * wm | ||
this.height = height * hm | ||
this.zoom = 1 | ||
if (view) { | ||
// get width and height from viewbox | ||
x = parseFloat(view[0]) | ||
y = parseFloat(view[1]) | ||
width = parseFloat(view[2]) | ||
height = parseFloat(view[3]) | ||
// calculate zoom accoring to viewbox | ||
this.zoom = ((this.width / this.height) > (width / height)) ? | ||
this.height / height : | ||
this.width / width | ||
// calculate real pixel dimensions on parent SVG.Doc element | ||
this.x = x | ||
this.y = y | ||
this.width = width | ||
this.height = height | ||
} | ||
}else{ | ||
// ensure source as object | ||
source = typeof source === 'string' ? | ||
source.match(reg).map(function(el){ return parseFloat(el) }) : | ||
Array.isArray(source) ? | ||
source : | ||
typeof source == 'object' ? | ||
[source.x, source.y, source.width, source.height] : | ||
arguments.length == 4 ? | ||
[].slice.call(arguments) : | ||
base | ||
this.x = source[0] | ||
this.y = source[1] | ||
this.width = source[2] | ||
this.height = source[3] | ||
} | ||
} | ||
while (height.unit == '%') { | ||
hm *= height.value | ||
height = new SVG.Number(he instanceof SVG.Doc ? he.parent().offsetHeight : he.parent().height()) | ||
he = he.parent() | ||
} | ||
// ensure defaults | ||
this.x = box.x | ||
this.y = box.y | ||
this.width = width * wm | ||
this.height = height * hm | ||
this.zoom = 1 | ||
if (view) { | ||
// get width and height from viewbox | ||
x = parseFloat(view[0]) | ||
y = parseFloat(view[1]) | ||
width = parseFloat(view[2]) | ||
height = parseFloat(view[3]) | ||
// calculate zoom accoring to viewbox | ||
this.zoom = ((this.width / this.height) > (width / height)) ? | ||
this.height / height : | ||
this.width / width | ||
// calculate real pixel dimensions on parent SVG.Doc element | ||
this.x = x | ||
this.y = y | ||
this.width = width | ||
this.height = height | ||
, extend: { | ||
toString: function() { | ||
return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height | ||
} | ||
, morph: function(v){ | ||
var v = arguments.length == 1 ? | ||
[v.x, v.y, v.width, v.height] : | ||
[].slice.call(arguments) | ||
this.destination = new SVG.ViewBox(v) | ||
return this | ||
} | ||
, at: function(pos) { | ||
if(!this.destination) return this | ||
return new SVG.ViewBox([ | ||
this.x + (this.destination.x - this.x) * pos | ||
, this.y + (this.destination.y - this.y) * pos | ||
, this.width + (this.destination.width - this.width) * pos | ||
, this.height + (this.destination.height - this.height) * pos | ||
]) | ||
} | ||
} | ||
} | ||
// | ||
SVG.extend(SVG.ViewBox, { | ||
// Parse viewbox to string | ||
toString: function() { | ||
return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height | ||
} | ||
}) |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
851919
116
18287
4100