From 88f214e91807fec172c32a49b2eb0b4808dc7f3c Mon Sep 17 00:00:00 2001 From: Dmitry Baranovskiy Date: Wed, 7 May 2014 18:37:05 +1000 Subject: [PATCH] Decouple all the things and bug fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • extract matrix, attar & paper.js • fix for transform for sag element • add Fragment to plugin call --- .gitignore | 2 + Gruntfile.js | 5 +- dist/snap.svg-min.js | 8 +- dist/snap.svg.js | 2947 +++++++++++++++++++++--------------------- doc/css/dr.css | 6 +- doc/reference.html | 2691 +------------------------------------- src/attr.js | 396 ++++++ src/matrix.js | 299 +++++ src/paper.js | 695 ++++++++++ src/svg.js | 1555 ++-------------------- test/paper.js | 15 +- test/primitives.js | 29 + test/test.html | 2 +- 13 files changed, 3126 insertions(+), 5524 deletions(-) create mode 100644 src/attr.js create mode 100644 src/matrix.js create mode 100644 src/paper.js diff --git a/.gitignore b/.gitignore index 0a563e6..258b01e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ TAGS *~ _* .DS_Store +node_modules +playground \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index d5dbdcd..a3471b9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -31,12 +31,15 @@ module.exports = function(grunt) { "./src/amd-banner.js", "./src/mina.js", "./src/svg.js", + "./src/matrix.js", + "./src/attr.js", + "./src/paper.js", "./src/path.js", "./src/set.js", "./src/equal.js", "./src/mouse.js", "./src/filter.js", - "./src/amd-footer.js", + "./src/amd-footer.js" ] } }, diff --git a/dist/snap.svg-min.js b/dist/snap.svg-min.js index d6892a5..e3aef2a 100644 --- a/dist/snap.svg-min.js +++ b/dist/snap.svg-min.js @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// build: 2014-05-05 -!function(a){var b,c,d="0.4.2",e="hasOwnProperty",f=/[\.\/]/,g="*",h=function(){},i=function(a,b){return a-b},j={n:{}},k=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=k.listeners(a),j=0,l=[],m={},n=[],o=b;b=a,c=0;for(var p=0,q=h.length;q>p;p++)"zIndex"in h[p]&&(l.push(h[p].zIndex),h[p].zIndex<0&&(m[h[p].zIndex]=h[p]));for(l.sort(i);l[j]<0;)if(e=m[l[j++]],n.push(e.apply(d,g)),c)return c=f,n;for(p=0;q>p;p++)if(e=h[p],"zIndex"in e)if(e.zIndex==l[j]){if(n.push(e.apply(d,g)),c)break;do if(j++,e=m[l[j]],e&&n.push(e.apply(d,g)),c)break;while(e)}else m[e.zIndex]=e;else if(n.push(e.apply(d,g)),c)break;return c=f,b=o,n.length?n:null};k._events=j,k.listeners=function(a){var b,c,d,e,h,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,h=m.length;h>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[g]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},k.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(f),d=j,e=0,g=c.length;g>e;e++)d=d.n,d=d.hasOwnProperty(c[e])&&d[c[e]]||(d[c[e]]={n:{}});for(d.f=d.f||[],e=0,g=d.f.length;g>e;e++)if(d.f[e]==b)return h;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},k.f=function(a){var b=[].slice.call(arguments,1);return function(){k.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},k.stop=function(){c=1},k.nt=function(a){return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(b):b},k.nts=function(){return b.split(f)},k.off=k.unbind=function(a,b){if(!a)return k._events=j={n:{}},void 0;var c,d,h,i,l,m,n,o=a.split(f),p=[j];for(i=0,l=o.length;l>i;i++)for(m=0;mi;i++)for(c=p[i];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++)if(c.f[m]==b){c.f.splice(m,1);break}!c.f.length&&delete c.f}for(d in c.n)if(c.n[e](d)&&c.n[d].f){var q=c.n[d].f;for(m=0,n=q.length;n>m;m++)if(q[m]==b){q.splice(m,1);break}!q.length&&delete c.n[d].f}}else{delete c.f;for(d in c.n)c.n[e](d)&&c.n[d].f&&delete c.n[d].f}c=c.n}},k.once=function(a,b){var c=function(){return k.unbind(a,c),b.apply(this,arguments)};return k.on(a,c)},k.version=d,k.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=k:"undefined"!=typeof define?define("eve",[],function(){return k}):a.eve=k}(this),function(a,b){"function"==typeof define&&define.amd?define(["eve"],function(c){return b(a,c)}):b(a,a.eve)}(this,function(a,b){var c=function(b){var c={},d=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},e=Array.isArray||function(a){return a instanceof Array||"[object Array]"==Object.prototype.toString.call(a)},f=0,g="M"+(+new Date).toString(36),h=function(){return g+(f++).toString(36)},i=Date.now||function(){return+new Date},j=function(a){var b=this;if(null==a)return b.s;var c=b.s-a;b.b+=b.dur*c,b.B+=b.dur*c,b.s=a},k=function(a){var b=this;return null==a?b.spd:(b.spd=a,void 0)},l=function(a){var b=this;return null==a?b.dur:(b.s=b.s*a/b.dur,b.dur=a,void 0)},m=function(){var a=this;delete c[a.id],a.update(),b("mina.stop."+a.id,a)},n=function(){var a=this;a.pdif||(delete c[a.id],a.update(),a.pdif=a.get()-a.b)},o=function(){var a=this;a.pdif&&(a.b=a.get()-a.pdif,delete a.pdif,c[a.id]=a)},p=function(){var a,b=this;if(e(b.start)){a=[];for(var c=0,d=b.start.length;d>c;c++)a[c]=+b.start[c]+(b.end[c]-b.start[c])*b.easing(b.s)}else a=+b.start+(b.end-b.start)*b.easing(b.s);b.set(a)},q=function(){var a=0;for(var e in c)if(c.hasOwnProperty(e)){var f=c[e],g=f.get();a++,f.s=(g-f.b)/(f.dur/f.spd),f.s>=1&&(delete c[e],f.s=1,a--,function(a){setTimeout(function(){b("mina.finish."+a.id,a)})}(f)),f.update()}a&&d(q)},r=function(a,b,e,f,g,i,s){var t={id:h(),start:a,end:b,b:e,s:0,dur:f-e,spd:1,get:g,set:i,easing:s||r.linear,status:j,speed:k,duration:l,stop:m,pause:n,resume:o,update:p};c[t.id]=t;var u,v=0;for(u in c)if(c.hasOwnProperty(u)&&(v++,2==v))break;return 1==v&&d(q),t};return r.time=i,r.getById=function(a){return c[a]||null},r.linear=function(a){return a},r.easeout=function(a){return Math.pow(a,1.7)},r.easein=function(a){return Math.pow(a,.48)},r.easeinout=function(a){if(1==a)return 1;if(0==a)return 0;var b=.48-a/1.04,c=Math.sqrt(.1734+b*b),d=c-b,e=Math.pow(Math.abs(d),1/3)*(0>d?-1:1),f=-c-b,g=Math.pow(Math.abs(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},r.backin=function(a){if(1==a)return 1;var b=1.70158;return a*a*((b+1)*a-b)},r.backout=function(a){if(0==a)return 0;a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},r.elastic=function(a){return a==!!a?a:Math.pow(2,-10*a)*Math.sin((a-.075)*2*Math.PI/.3)+1},r.bounce=function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b},a.mina=r,r}("undefined"==typeof b?function(){}:b),d=function(){function d(a,b){if(a){if(a.tagName)return z(a);if(f(a,"array")&&d.set)return d.set.apply(d,a);if(a instanceof u)return a;if(null==b)return a=J.doc.querySelector(a),z(a)}return a=null==a?"100%":a,b=null==b?"100%":b,new y(a,b)}function e(a,b){if(b){if("#text"==a&&(a=J.doc.createTextNode(b.text||"")),"string"==typeof a&&(a=e(a)),"string"==typeof b)return"xlink:"==b.substring(0,6)?a.getAttributeNS(gb,b.substring(6)):"xml:"==b.substring(0,4)?a.getAttributeNS(hb,b.substring(4)):a.getAttribute(b);for(var c in b)if(b[K](c)){var d=L(b[c]);d?"xlink:"==c.substring(0,6)?a.setAttributeNS(gb,c.substring(6),d):"xml:"==c.substring(0,4)?a.setAttributeNS(hb,c.substring(4),d):a.setAttribute(c,d):a.removeAttribute(c)}}else a=J.doc.createElementNS(hb,a);return a}function f(a,b){return b=L.prototype.toLowerCase.call(b),"finite"==b?isFinite(a):"array"==b&&(a instanceof Array||Array.isArray&&Array.isArray(a))?!0:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||V.call(a).slice(8,-1).toLowerCase()==b}function h(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[K](c)&&(b[c]=h(a[c]));return b}function i(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function j(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),g=d.cache=d.cache||{},h=d.count=d.count||[];return g[K](f)?(i(h,f),c?c(g[f]):g[f]):(h.length>=1e3&&delete g[h.shift()],h.push(f),g[f]=a.apply(b,e),c?c(g[f]):g[f])}return d}function k(a,b,c,d,e,f){if(null==e){var g=a-c,h=b-d;return g||h?(180+180*O.atan2(-h,-g)/S+360)%360:0}return k(a,b,e,f)-k(c,d,e,f)}function l(a){return a%360*S/180}function m(a){return 180*a/S%360}function n(a,b,c,d,e,f){return null==b&&"[object SVGMatrix]"==V.call(a)?(this.a=a.a,this.b=a.b,this.c=a.c,this.d=a.d,this.e=a.e,this.f=a.f,void 0):(null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0),void 0)}function o(a){var b=[];return a=a.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g,function(a,c,d){return d=d.split(/\s*,\s*|\s+/),"rotate"==c&&1==d.length&&d.push(0,0),"scale"==c&&(d.length>2?d=d.slice(0,2):2==d.length&&d.push(0,0),1==d.length&&d.push(d[0],0,0)),"skewX"==c?b.push(["m",1,0,O.tan(l(d[0])),1,0,0]):"skewY"==c?b.push(["m",1,O.tan(l(d[0])),0,1,0,0]):b.push([c.charAt(0)].concat(d)),a}),b}function p(a,b){var c=rb(a),d=new n;if(c)for(var e=0,f=c.length;f>e;e++){var g,h,i,j,k,l=c[e],m=l.length,o=L(l[0]).toLowerCase(),p=l[0]!=o,q=p?d.invert():0;"t"==o&&2==m?d.translate(l[1],0):"t"==o&&3==m?p?(g=q.x(0,0),h=q.y(0,0),i=q.x(l[1],l[2]),j=q.y(l[1],l[2]),d.translate(i-g,j-h)):d.translate(l[1],l[2]):"r"==o?2==m?(k=k||b,d.rotate(l[1],k.x+k.width/2,k.y+k.height/2)):4==m&&(p?(i=q.x(l[2],l[3]),j=q.y(l[2],l[3]),d.rotate(l[1],i,j)):d.rotate(l[1],l[2],l[3])):"s"==o?2==m||3==m?(k=k||b,d.scale(l[1],l[m-1],k.x+k.width/2,k.y+k.height/2)):4==m?p?(i=q.x(l[2],l[3]),j=q.y(l[2],l[3]),d.scale(l[1],l[1],i,j)):d.scale(l[1],l[1],l[2],l[3]):5==m&&(p?(i=q.x(l[3],l[4]),j=q.y(l[3],l[4]),d.scale(l[1],l[2],i,j)):d.scale(l[1],l[2],l[3],l[4])):"m"==o&&7==m&&d.add(l[1],l[2],l[3],l[4],l[5],l[6])}return d}function q(a,b){if(null==b){var c=!0;if(b="linearGradient"==a.type||"radialGradient"==a.type?a.node.getAttribute("gradientTransform"):"pattern"==a.type?a.node.getAttribute("patternTransform"):a.node.getAttribute("transform"),!b)return new n;b=o(b)}else b=d._.rgTransform.test(b)?L(b).replace(/\.{3}|\u2026/g,a._.transform||T):o(b),f(b,"array")&&(b=d.path?d.path.toString.call(b):L(b)),a._.transform=b;var e=p(b,a.getBBox(1));return c?e:(a.matrix=e,void 0)}function r(a){var b=a.node.ownerSVGElement&&z(a.node.ownerSVGElement)||a.node.parentNode&&z(a.node.parentNode)||d.select("svg")||d(0,0),c=b.select("defs"),e=null==c?!1:c.node;return e||(e=x("defs",b.node).node),e}function s(a,b,c){function d(a){return null==a?T:a==+a?a:(e(j,{width:a}),j.getBBox().width)}function f(a){return null==a?T:a==+a?a:(e(j,{height:a}),j.getBBox().height)}function g(d,e){null==b?i[d]=e(a.attr(d)||0):d==b&&(i=e(null==c?a.attr(d)||0:c))}var h=r(a),i={},j=h.querySelector(".svg---mgr");switch(j||(j=e("rect"),e(j,{width:10,height:10,"class":"svg---mgr"}),h.appendChild(j)),a.type){case"rect":g("rx",d),g("ry",f);case"image":g("width",d),g("height",f);case"text":g("x",d),g("y",f);break;case"circle":g("cx",d),g("cy",f),g("r",d);break;case"ellipse":g("cx",d),g("cy",f),g("rx",d),g("ry",f);break;case"line":g("x1",d),g("x2",d),g("y1",f),g("y2",f);break;case"marker":g("refX",d),g("markerWidth",d),g("refY",f),g("markerHeight",f);break;case"radialGradient":g("fx",d),g("fy",f);break;case"tspan":g("dx",d),g("dy",f);break;default:g(b,d)}return i}function t(a){f(a,"array")||(a=Array.prototype.slice.call(arguments,0));for(var b=0,c=0,d=this.node;this[b];)delete this[b++];for(b=0;bc;c++)if(b=b||a[c])return b}function w(a){this.node=a}function x(a,b){var c=e(a);b.appendChild(c);var d=z(c);return d}function y(a,b){var c,d,f,g=y.prototype;if(a&&"svg"==a.tagName){if(a.snap in ib)return ib[a.snap];var h=a.ownerDocument;c=new u(a),d=a.getElementsByTagName("desc")[0],f=a.getElementsByTagName("defs")[0],d||(d=e("desc"),d.appendChild(h.createTextNode("Created with Snap")),c.node.appendChild(d)),f||(f=e("defs"),c.node.appendChild(f)),c.defs=f;for(var i in g)g[K](i)&&(c[i]=g[i]);c.paper=c.root=c}else c=x("svg",J.doc.body),e(c.node,{height:b,version:1.1,width:a,xmlns:hb});return c}function z(a){return a?a instanceof u||a instanceof w?a:"svg"==a.tagName?new y(a):"object"==a.tagName.toLowerCase()&&"image/svg+xml"==a.type?new y(a.contentDocument.getElementsByTagName("svg")[0]):new u(a):a}function A(){return this.selectAll("stop")}function B(a,b){var c=e("stop"),f={offset:+b+"%"};return a=d.color(a),f["stop-color"]=a.hex,a.opacity<1&&(f["stop-opacity"]=a.opacity),e(c,f),this.node.appendChild(c),this}function C(){if("linearGradient"==this.type){var a=e(this.node,"x1")||0,b=e(this.node,"x2")||1,c=e(this.node,"y1")||0,f=e(this.node,"y2")||0;return d._.box(a,c,O.abs(b-a),O.abs(f-c))}var g=this.node.cx||.5,h=this.node.cy||.5,i=this.node.r||0;return d._.box(g-i,h-i,2*i,2*i)}function D(a,c){function d(a,b){for(var c=(b-j)/(a-k),d=k;a>d;d++)h[d].offset=+(+j+c*(d-k)).toFixed(2);k=a,j=b}var f,g=v(b("snap.util.grad.parse",null,c));if(!g)return null;g.params.unshift(a),f="l"==g.type.toLowerCase()?E.apply(0,g.params):F.apply(0,g.params),g.type!=g.type.toLowerCase()&&e(f.node,{gradientUnits:"userSpaceOnUse"});var h=g.stops,i=h.length,j=0,k=0;i--;for(var l=0;i>l;l++)"offset"in h[l]&&d(l,h[l].offset);for(h[i].offset=h[i].offset||100,d(i,h[i].offset),l=0;i>=l;l++){var m=h[l];f.addStop(m.color,m.offset)}return f}function E(a,b,c,d,f){var g=x("linearGradient",a);return g.stops=A,g.addStop=B,g.getBBox=C,null!=b&&e(g.node,{x1:b,y1:c,x2:d,y2:f}),g}function F(a,b,c,d,f,g){var h=x("radialGradient",a);return h.stops=A,h.addStop=B,h.getBBox=C,null!=b&&e(h.node,{cx:b,cy:c,r:d}),null!=f&&null!=g&&e(h.node,{fx:f,fy:g}),h}function G(a){return function(c){if(b.stop(),c instanceof w&&1==c.node.childNodes.length&&("radialGradient"==c.node.firstChild.tagName||"linearGradient"==c.node.firstChild.tagName||"pattern"==c.node.firstChild.tagName)&&(c=c.node.firstChild,r(this).appendChild(c),c=z(c)),c instanceof u)if("radialGradient"==c.type||"linearGradient"==c.type||"pattern"==c.type){c.node.id||e(c.node,{id:c.id});var f=jb(c.node.id)}else f=c.attr(a);else if(f=d.color(c),f.error){var g=D(r(this),c);g?(g.node.id||e(g.node,{id:g.id}),f=jb(g.node.id)):f=c}else f=L(f);var h={};h[a]=f,e(this.node,h),this.node.style[a]=T}}function H(a){for(var b=[],c=a.childNodes,d=0,e=c.length;e>d;d++){var f=c[d];3==f.nodeType&&b.push(f.nodeValue),"tspan"==f.tagName&&(1==f.childNodes.length&&3==f.firstChild.nodeType?b.push(f.firstChild.nodeValue):b.push(H(f)))}return b}function I(){return b.stop(),this.node.style.fontSize}d.version="0.3.0",d.toString=function(){return"Snap v"+this.version},d._={};var J={win:a,doc:a.document};d._.glob=J;var K="hasOwnProperty",L=String,M=parseFloat,N=parseInt,O=Math,P=O.max,Q=O.min,R=O.abs,S=(O.pow,O.PI),T=(O.round,""),U=" ",V=Object.prototype.toString,W=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,X=/^url\(#?([^)]+)\)$/,Y=" \n \f\r   ᠎              \u2028\u2029",Z=new RegExp("[,"+Y+"]+"),$=(new RegExp("["+Y+"]","g"),new RegExp("["+Y+"]*,["+Y+"]*")),_={hs:1,rg:1},ab=new RegExp("([a-z])["+Y+",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?["+Y+"]*,?["+Y+"]*)+)","ig"),bb=new RegExp("([rstm])["+Y+",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?["+Y+"]*,?["+Y+"]*)+)","ig"),cb=new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)["+Y+"]*,?["+Y+"]*","ig"),db=0,eb="S"+(+new Date).toString(36),fb=function(){return eb+(db++).toString(36)},gb="http://www.w3.org/1999/xlink",hb="http://www.w3.org/2000/svg",ib={},jb=d.url=function(a){return"url('#"+a+"')"};d._.$=e,d._.id=fb,d.format=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return L(b).replace(a,function(a,b){return c(a,b,d)})}}();var kb=function(){function a(){this.parentNode.removeChild(this)}return function(b,c){var d=J.doc.createElement("img"),e=J.doc.body;d.style.cssText="position:absolute;left:-9999em;top:-9999em",d.onload=function(){c.call(d),d.onload=d.onerror=null,e.removeChild(d)},d.onerror=a,e.appendChild(d),d.src=b}}();d._.clone=h,d._.cacher=j,d.rad=l,d.deg=m,d.angle=k,d.is=f,d.snapTo=function(a,b,c){if(c=f(c,"finite")?c:10,f(a,"array")){for(var d=a.length;d--;)if(R(a[d]-b)<=c)return a[d]}else{a=+a;var e=b%a;if(c>e)return b-e;if(e>a-c)return b-e+a}return b},function(a){function b(a){return a[0]*a[0]+a[1]*a[1]}function c(a){var c=O.sqrt(b(a));a[0]&&(a[0]/=c),a[1]&&(a[1]/=c)}a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof n&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++)for(h=0;3>h;h++){for(j=0,i=0;3>i;i++)j+=l[g][i]*m[i][h];k[g][h]=j}return this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2],this},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new n(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new n(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){return this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){return null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d),this},a.rotate=function(a,b,c){a=l(a),b=b||0,c=c||0;var d=+O.cos(a).toFixed(9),e=+O.sin(a).toFixed(9);return this.add(d,e,-e,d,b,c),this.add(1,0,0,1,-b,-c)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[L.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.determinant=function(){return this.a*this.d-this.b*this.c},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var d=[[this.a,this.c],[this.b,this.d]];a.scalex=O.sqrt(b(d[0])),c(d[0]),a.shear=d[0][0]*d[1][0]+d[0][1]*d[1][1],d[1]=[d[1][0]-d[0][0]*a.shear,d[1][1]-d[0][1]*a.shear],a.scaley=O.sqrt(b(d[1])),c(d[1]),a.shear/=a.scaley,this.determinant()<0&&(a.scalex=-a.scalex);var e=-d[0][1],f=d[1][1];return 0>f?(a.rotate=m(O.acos(f)),0>e&&(a.rotate=360-a.rotate)):a.rotate=m(O.asin(e)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this.split();return+b.shear.toFixed(9)?"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]:(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[+b.dx.toFixed(4),+b.dy.toFixed(4)]:T)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:T)+(b.rotate?"r"+[+b.rotate.toFixed(4),0,0]:T))}}(n.prototype),d.Matrix=n,d.getRGB=j(function(a){if(!a||(a=L(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:ob};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:ob};if(!(_[K](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=lb(a)),!a)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:ob};var b,c,e,g,h,i,j=a.match(W);return j?(j[2]&&(e=N(j[2].substring(5),16),c=N(j[2].substring(3,5),16),b=N(j[2].substring(1,3),16)),j[3]&&(e=N((h=j[3].charAt(3))+h,16),c=N((h=j[3].charAt(2))+h,16),b=N((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4].split($),b=M(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),c=M(i[1]),"%"==i[1].slice(-1)&&(c*=2.55),e=M(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=M(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5].split($),b=M(i[0]),"%"==i[0].slice(-1)&&(b/=100),c=M(i[1]),"%"==i[1].slice(-1)&&(c/=100),e=M(i[2]),"%"==i[2].slice(-1)&&(e/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=M(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),d.hsb2rgb(b,c,e,g)):j[6]?(i=j[6].split($),b=M(i[0]),"%"==i[0].slice(-1)&&(b/=100),c=M(i[1]),"%"==i[1].slice(-1)&&(c/=100),e=M(i[2]),"%"==i[2].slice(-1)&&(e/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=M(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),d.hsl2rgb(b,c,e,g)):(b=Q(O.round(b),255),c=Q(O.round(c),255),e=Q(O.round(e),255),g=Q(P(g,0),1),j={r:b,g:c,b:e,toString:ob},j.hex="#"+(16777216|e|c<<8|b<<16).toString(16).slice(1),j.opacity=f(g,"finite")?g:1,j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:ob}},d),d.hsb=j(function(a,b,c){return d.hsb2rgb(a,b,c).hex}),d.hsl=j(function(a,b,c){return d.hsl2rgb(a,b,c).hex}),d.rgb=j(function(a,b,c,d){if(f(d,"finite")){var e=O.round;return"rgba("+[e(a),e(b),e(c),+d.toFixed(2)]+")"}return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)});var lb=function(a){var b=J.doc.getElementsByTagName("head")[0],c="rgb(255, 0, 0)";return lb=j(function(a){if("red"==a.toLowerCase())return c;b.style.color=c,b.style.color=a;var d=J.doc.defaultView.getComputedStyle(b,T).getPropertyValue("color");return d==c?null:d}),lb(a)},mb=function(){return"hsb("+[this.h,this.s,this.b]+")"},nb=function(){return"hsl("+[this.h,this.s,this.l]+")"},ob=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},pb=function(a,b,c){if(null==b&&f(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(c=a.b,b=a.g,a=a.r),null==b&&f(a,string)){var e=d.getRGB(a);a=e.r,b=e.g,c=e.b}return(a>1||b>1||c>1)&&(a/=255,b/=255,c/=255),[a,b,c]},qb=function(a,b,c,e){a=O.round(255*a),b=O.round(255*b),c=O.round(255*c);var g={r:a,g:b,b:c,opacity:f(e,"finite")?e:1,hex:d.rgb(a,b,c),toString:ob};return f(e,"finite")&&(g.opacity=e),g};d.color=function(a){var b;return f(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=d.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):f(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=d.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):(f(a,"string")&&(a=d.getRGB(a)),f(a,"object")&&"r"in a&&"g"in a&&"b"in a&&!("error"in a)?(b=d.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=d.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1,a.error=1)),a.toString=ob,a},d.hsb2rgb=function(a,b,c,d){f(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,g,h,i,j;return a=a%360/60,j=c*b,i=j*(1-R(a%2-1)),e=g=h=c-j,a=~~a,e+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],qb(e,g,h,d)},d.hsl2rgb=function(a,b,c,d){f(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,g,h,i,j;return a=a%360/60,j=2*b*(.5>c?c:1-c),i=j*(1-R(a%2-1)),e=g=h=c-j/2,a=~~a,e+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],qb(e,g,h,d)},d.rgb2hsb=function(a,b,c){c=pb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=P(a,b,c),g=f-Q(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=60*((d+360)%6)/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:mb}},d.rgb2hsl=function(a,b,c){c=pb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=P(a,b,c),h=Q(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=60*((d+360)%6)/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:nb}},d.parsePathString=function(a){if(!a)return null;var b=d.path(a);if(b.arr)return d.path.clone(b.arr);var c={a:7,c:6,o:2,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,u:3,z:0},e=[];return f(a,"array")&&f(a[0],"array")&&(e=d.path.clone(a)),e.length||L(a).replace(ab,function(a,b,d){var f=[],g=b.toLowerCase();if(d.replace(cb,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b].concat(f.splice(0,2))),g="l",b="m"==b?"l":"L"),"o"==g&&1==f.length&&e.push([b,f[0]]),"r"==g)e.push([b].concat(f));else for(;f.length>=c[g]&&(e.push([b].concat(f.splice(0,c[g]))),c[g]););}),e.toString=d.path.toString,b.arr=d.path.clone(e),e};var rb=d.parseTransformString=function(a){if(!a)return null;var b=[];return f(a,"array")&&f(a[0],"array")&&(b=d.path.clone(a)),b.length||L(a).replace(bb,function(a,c,d){var e=[];c.toLowerCase(),d.replace(cb,function(a,b){b&&e.push(+b)}),b.push([c].concat(e))}),b.toString=d.path.toString,b};d._.svgTransform2string=o,d._.rgTransform=new RegExp("^[a-z]["+Y+"]*-?\\.?\\d","i"),d._.transform2matrix=p,d._unit2px=s,J.doc.contains||J.doc.compareDocumentPosition?function(a,b){var c=9==a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a==d||!(!d||1!=d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b;)if(b=b.parentNode,b==a)return!0;return!1},d._.getSomeDefs=r,d.select=function(a){return z(J.doc.querySelector(a))},d.selectAll=function(a){for(var b=J.doc.querySelectorAll(a),c=(d.set||Array)(),e=0;ej;j++){d=f[j],b(d,"fill"),b(d,"stroke"),b(d,"filter"),b(d,"mask"),b(d,"clip-path"),c(d);var l=e(d.node,"id");l&&(e(d.node,{id:d.id}),h.push({old:l,id:d.id}))}for(j=0,k=h.length;k>j;j++){var m=i[h[j].old];if(m)for(var n=0,o=m.length;o>n;n++)m[n](h[j].id)}}function h(a,b,c){return function(d){var e=d.slice(a,b);return 1==e.length&&(e=e[0]),c?c(e):e}}function i(a){return function(){var b=a?"<"+this.type:"",c=this.node.attributes,d=this.node.childNodes;if(a)for(var e=0,f=c.length;f>e;e++)b+=" "+c[e].name+'="'+c[e].value.replace(/"/g,'\\"')+'"';if(d.length){for(a&&(b+=">"),e=0,f=d.length;f>e;e++)3==d[e].nodeType?b+=d[e].nodeValue:1==d[e].nodeType&&(b+=z(d[e]).toString());a&&(b+="")}else a&&(b+="/>");return b}}a.attr=function(a,c){var d=this;if(d.node,!a)return d;if(f(a,"string")){if(!(arguments.length>1))return v(b("snap.util.getattr."+a,d));var e={};e[a]=c,a=e}for(var g in a)a[K](g)&&b("snap.util.attr."+g,d,a[g]);return d},a.getBBox=function(a){var b=this;if(b.removed)return{};if("use"==b.type)if(b.original)b=b.original;else{var c=b.attr("xlink:href");b=b.node.ownerDocument.getElementById(c.substring(c.indexOf("#")+1))}var e=b._;return a?(e.bboxwt=d.path.get[b.type]?d.path.getBBox(b.realPath=d.path.get[b.type](b)):d._.box(b.node.getBBox()),d._.box(e.bboxwt)):(b.realPath=(d.path.get[b.type]||d.path.get.deflt)(b),b.matrix=b.transform().localMatrix,e.bbox=d.path.getBBox(d.path.map(b.realPath,b.matrix)),d._.box(e.bbox))};var j=function(){return this.string};a.transform=function(a){var b=this._;if(null==a){for(var c,d=this,f=new n(this.node.getCTM()),g=q(this),h=[g],i=new n,k=g.toTransformString(),l=L(g)==L(this.matrix)?b.transform:k;(d=d.parent())&&"svg"!=d.type;)h.push(q(d));for(c=h.length;c--;)i.add(h[c]);return{string:l,globalMatrix:f,totalMatrix:i,localMatrix:g,diffMatrix:f.clone().add(g.invert()),global:f.toTransformString(),total:i.toTransformString(),local:k,toString:j}}return a instanceof n?this.matrix=a:q(this,a),this.node&&("linearGradient"==this.type||"radialGradient"==this.type?e(this.node,{gradientTransform:this.matrix}):"pattern"==this.type?e(this.node,{patternTransform:this.matrix}):e(this.node,{transform:this.matrix})),this},a.parent=function(){return z(this.node.parentNode)},a.append=a.add=function(a){if(a){if("set"==a.type){var b=this;return a.forEach(function(a){b.add(a)}),this}a=z(a),this.node.appendChild(a.node),a.paper=this.paper}return this},a.appendTo=function(a){return a&&(a=z(a),a.append(this)),this},a.prepend=function(a){if(a){a=z(a);var b=a.parent();this.node.insertBefore(a.node,this.node.firstChild),this.add&&this.add(),a.paper=this.paper,this.parent()&&this.parent().add(),b&&b.add()}return this},a.prependTo=function(a){return a=z(a),a.prepend(this),this},a.before=function(a){if("set"==a.type){var b=this;return a.forEach(function(a){var c=a.parent();b.node.parentNode.insertBefore(a.node,b.node),c&&c.add()}),this.parent().add(),this}a=z(a);var c=a.parent();return this.node.parentNode.insertBefore(a.node,this.node),this.parent()&&this.parent().add(),c&&c.add(),a.paper=this.paper,this},a.after=function(a){a=z(a);var b=a.parent();return this.node.nextSibling?this.node.parentNode.insertBefore(a.node,this.node.nextSibling):this.node.parentNode.appendChild(a.node),this.parent()&&this.parent().add(),b&&b.add(),a.paper=this.paper,this},a.insertBefore=function(a){a=z(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},a.insertAfter=function(a){a=z(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node.nextSibling),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},a.remove=function(){var a=this.parent();return this.node.parentNode&&this.node.parentNode.removeChild(this.node),delete this.paper,this.removed=!0,a&&a.add(),this},a.select=function(a){return z(this.node.querySelector(a))},a.selectAll=function(a){for(var b=this.node.querySelectorAll(a),c=(d.set||Array)(),e=0;eb;b++)a[b].stop();return this},a.animate=function(a,d,e,g){"function"!=typeof e||e.length||(g=e,e=c.linear),a instanceof l&&(g=a.callback,e=a.easing,d=e.dur,a=a.attr);var i,j,k,m,n=[],o=[],p={},q=this;for(var r in a)if(a[K](r)){q.equal?(m=q.equal(r,L(a[r])),i=m.from,j=m.to,k=m.f):(i=+q.attr(r),j=+a[r]);var s=f(i,"array")?i.length:1;p[r]=h(n.length,n.length+s,k),n=n.concat(i),o=o.concat(j)}var t=c.time(),u=c(n,o,t,t+d,c.time,function(a){var b={};for(var c in p)p[K](c)&&(b[c]=p[c](a));q.attr(b)},e);return q.anims[u.id]=u,u._attrs=a,u._callback=g,b("snap.animcreated."+q.id,u),b.once("mina.finish."+u.id,function(){delete q.anims[u.id],g&&g.call(q)}),b.once("mina.stop."+u.id,function(){delete q.anims[u.id]}),q};var m={};a.data=function(a,c){var e=m[this.id]=m[this.id]||{};if(0==arguments.length)return b("snap.data.get."+this.id,this,e,null),e;if(1==arguments.length){if(d.is(a,"object")){for(var f in a)a[K](f)&&this.data(f,a[f]);return this}return b("snap.data.get."+this.id,this,e[a],a),e[a] -}return e[a]=c,b("snap.data.set."+this.id,this,c,a),this},a.removeData=function(a){return null==a?m[this.id]={}:m[this.id]&&delete m[this.id][a],this},a.outerSVG=a.toString=i(1),a.innerSVG=i()}(u.prototype),d.parse=function(a){var b=J.doc.createDocumentFragment(),c=!0,d=J.doc.createElement("div");if(a=L(a),a.match(/^\s*<\s*svg(?:\s|>)/)||(a=""+a+"",c=!1),d.innerHTML=a,a=d.getElementsByTagName("svg")[0])if(c)b=a;else for(;a.firstChild;)b.appendChild(a.firstChild);return d.innerHTML=T,new w(b)},w.prototype.select=u.prototype.select,w.prototype.selectAll=u.prototype.selectAll,d.fragment=function(){for(var a=Array.prototype.slice.call(arguments,0),b=J.doc.createDocumentFragment(),c=0,e=a.length;e>c;c++){var f=a[c];f.node&&f.node.nodeType&&b.appendChild(f.node),f.nodeType&&b.appendChild(f),"string"==typeof f&&b.appendChild(d.parse(f).node)}return new w(b)},function(a){a.el=function(a,b){return x(a,this.node).attr(b)},a.rect=function(a,b,c,d,e,g){var h;return null==g&&(g=e),f(a,"object")&&"[object Object]"==a?h=a:null!=a&&(h={x:a,y:b,width:c,height:d},null!=e&&(h.rx=e,h.ry=g)),this.el("rect",h)},a.circle=function(a,b,c){var d;return f(a,"object")&&"[object Object]"==a?d=a:null!=a&&(d={cx:a,cy:b,r:c}),this.el("circle",d)},a.image=function(a,b,c,d,g){var h=x("image",this.node);if(f(a,"object")&&"src"in a)h.attr(a);else if(null!=a){var i={"xlink:href":a,preserveAspectRatio:"none"};null!=b&&null!=c&&(i.x=b,i.y=c),null!=d&&null!=g?(i.width=d,i.height=g):kb(a,function(){e(h.node,{width:this.offsetWidth,height:this.offsetHeight})}),e(h.node,i)}return h},a.ellipse=function(a,b,c,d){var e=x("ellipse",this.node);return f(a,"object")&&"[object Object]"==a?e.attr(a):null!=a&&e.attr({cx:a,cy:b,rx:c,ry:d}),e},a.path=function(a){var b=x("path",this.node);return f(a,"object")&&!f(a,"array")?b.attr(a):a&&b.attr({d:a}),b},a.group=a.g=function(a){var b=x("g",this.node);return 1==arguments.length&&a&&!a.type?b.attr(a):arguments.length&&b.add(Array.prototype.slice.call(arguments,0)),b},a.svg=function(a,b,c,d,e,g,h,i){var j=x("svg",this.node),k={};return f(a,"object")&&null==b?k=a:(null!=a&&(k.x=a),null!=b&&(k.y=b),null!=c&&(k.width=c),null!=d&&(k.height=d),null!=e&&null!=g&&null!=h&&null!=i&&(k.viewBox=[e,g,h,i])),j.attr(k),j},a.mask=function(a){var b=x("mask",this.node);return 1==arguments.length&&a&&!a.type?b.attr(a):arguments.length&&b.add(Array.prototype.slice.call(arguments,0)),b},a.ptrn=function(a,b,c,d,e,g,h,i){var j=x("pattern",this.node);if(arguments.length)null==e&&(e=a,g=b,h=c,i=d),k={x:a,y:b,width:c,height:d,patternUnits:"userSpaceOnUse",viewBox:[e,g,h,i].join(" ")};else var k={patternUnits:"userSpaceOnUse"};return f(a,"object")&&(k=a),j.attr(k),j},a.use=function(a){if(null!=a){var b=x("use",this.node);return a instanceof u&&(a.attr("id")||a.attr({id:fb()}),a=a.attr("id")),a&&b.attr({"xlink:href":a}),b}return u.prototype.use.call(this)},a.text=function(a,b,c){var d=x("text",this.node);return f(a,"object")?d.attr(a):null!=a&&d.attr({x:a,y:b,text:c||""}),d},a.line=function(a,b,c,d){var e=x("line",this.node);return f(a,"object")?e.attr(a):null!=a&&e.attr({x1:a,x2:c,y1:b,y2:d}),e},a.polyline=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b=x("polyline",this.node);return f(a,"object")&&!f(a,"array")?b.attr(a):null!=a&&b.attr({points:a}),b},a.polygon=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b=x("polygon",this.node);return f(a,"object")&&!f(a,"array")?b.attr(a):null!=a&&b.attr({points:a}),b},function(){a.gradient=function(a){return D(this.defs,a)},a.gradientLinear=function(a,b,c,d){return E(this.defs,a,b,c,d)},a.gradientRadial=function(a,b,c,d,e){return F(this.defs,a,b,c,d,e)},a.toString=function(){var a,b=J.doc.createDocumentFragment(),c=J.doc.createElement("div"),d=this.node.cloneNode(!0);return b.appendChild(c),c.appendChild(d),e(d,{xmlns:hb}),a=c.innerHTML,b.removeChild(b.firstChild),a},a.clear=function(){for(var a,b=this.node.firstChild;b;)a=b.nextSibling,"defs"!=b.tagName&&b.parentNode.removeChild(b),b=a}}()}(y.prototype),d.ajax=function(a,c,d,e){var g=new XMLHttpRequest,h=fb();if(g){if(f(c,"function"))e=d,d=c,c=null;else if(f(c,"object")){var i=[];for(var j in c)c.hasOwnProperty(j)&&i.push(encodeURIComponent(j)+"="+encodeURIComponent(c[j]));c=i.join("&")}return g.open(c?"POST":"GET",a,!0),g.setRequestHeader("X-Requested-With","XMLHttpRequest"),c&&g.setRequestHeader("Content-type","application/x-www-form-urlencoded"),d&&(b.once("snap.ajax."+h+".0",d),b.once("snap.ajax."+h+".200",d),b.once("snap.ajax."+h+".304",d)),g.onreadystatechange=function(){4==g.readyState&&b("snap.ajax."+h+"."+g.status,e,g)},4==g.readyState?g:(g.send(c),g)}},d.load=function(a,b,c){d.ajax(a,function(a){var e=d.parse(a.responseText);c?b.call(c,e):b(e)})},b.on("snap.util.attr.mask",function(a){if(a instanceof u||a instanceof w){if(b.stop(),a instanceof w&&1==a.node.childNodes.length&&(a=a.node.firstChild,r(this).appendChild(a),a=z(a)),"mask"==a.type)var c=a;else c=x("mask",r(this)),c.node.appendChild(a.node),!c.node.id&&e(c.node,{id:c.id});e(this.node,{mask:jb(c.id)})}}),function(a){b.on("snap.util.attr.clip",a),b.on("snap.util.attr.clip-path",a),b.on("snap.util.attr.clipPath",a)}(function(a){if(a instanceof u||a instanceof w){if(b.stop(),"clipPath"==a.type)var c=a;else c=x("clipPath",r(this)),c.node.appendChild(a.node),!c.node.id&&e(c.node,{id:c.id});e(this.node,{"clip-path":jb(c.id)})}}),b.on("snap.util.attr.fill",G("fill")),b.on("snap.util.attr.stroke",G("stroke"));var sb=/^([lr])(?:\(([^)]*)\))?(.*)$/i;b.on("snap.util.grad.parse",function(a){a=L(a);var b=a.match(sb);if(!b)return null;var c=b[1],d=b[2],e=b[3];return d=d.split(/\s*,\s*/).map(function(a){return+a==a?+a:a}),1==d.length&&0==d[0]&&(d=[]),e=e.split("-"),e=e.map(function(a){a=a.split(":");var b={color:a[0]};return a[1]&&(b.offset=parseFloat(a[1])),b}),{type:c,params:d,stops:e}}),b.on("snap.util.attr.d",function(a){b.stop(),f(a,"array")&&f(a[0],"array")&&(a=d.path.toString.call(a)),a=L(a),a.match(/[ruo]/i)&&(a=d.path.toAbsolute(a)),e(this.node,{d:a})})(-1),b.on("snap.util.attr.#text",function(a){b.stop(),a=L(a);for(var c=J.doc.createTextNode(a);this.node.firstChild;)this.node.removeChild(this.node.firstChild);this.node.appendChild(c)})(-1),b.on("snap.util.attr.path",function(a){b.stop(),this.attr({d:a})})(-1),b.on("snap.util.attr.class",function(a){b.stop(),this.node.className.baseVal=a})(-1),b.on("snap.util.attr.viewBox",function(a){var c;c=f(a,"object")&&"x"in a?[a.x,a.y,a.width,a.height].join(" "):f(a,"array")?a.join(" "):a,e(this.node,{viewBox:c}),b.stop()})(-1),b.on("snap.util.attr.transform",function(a){this.transform(a),b.stop()})(-1),b.on("snap.util.attr.r",function(a){"rect"==this.type&&(b.stop(),e(this.node,{rx:a,ry:a}))})(-1),b.on("snap.util.attr.textpath",function(a){if(b.stop(),"text"==this.type){var c,d,g;if(!a&&this.textPath){for(d=this.textPath;d.node.firstChild;)this.node.appendChild(d.node.firstChild);return d.remove(),delete this.textPath,void 0}if(f(a,"string")){var h=r(this),i=z(h.parentNode).path(a);h.appendChild(i.node),c=i.id,i.attr({id:c})}else a=z(a),a instanceof u&&(c=a.attr("id"),c||(c=a.id,a.attr({id:c})));if(c)if(d=this.textPath,g=this.node,d)d.attr({"xlink:href":"#"+c});else{for(d=e("textPath",{"xlink:href":"#"+c});g.firstChild;)d.appendChild(g.firstChild);g.appendChild(d),this.textPath=z(d)}}})(-1),b.on("snap.util.attr.text",function(a){if("text"==this.type){for(var c=this.node,d=function(a){var b=e("tspan");if(f(a,"array"))for(var c=0;cr;r++){if(l=a[r],"M"==l[0])j=+l[1],k=+l[2];else{if(m=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6]),q+m>f){if(d&&!p.start){if(n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q),o+=["C"+e(n.start.x),e(n.start.y),e(n.m.x),e(n.m.y),e(n.x),e(n.y)],h)return o;p.start=o,o=["M"+e(n.x),e(n.y)+"C"+e(n.n.x),e(n.n.y),e(n.end.x),e(n.end.y),e(l[5]),e(l[6])].join(),q+=m,j=+l[5],k=+l[6];continue}if(!c&&!d)return n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q)}q+=m,j=+l[5],k=+l[6]}o+=l.shift()+l}return p.end=o,n=c?q:d?p:i(j,k,l[0],l[1],l[2],l[3],l[4],l[5],1)},null,a._.clone)}function i(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/O;return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}}function j(b,c,e,f,g,h,i,j){a.is(b,"array")||(b=[b,c,e,f,g,h,i,j]);var k=D.apply(null,b);return d(k.min.x,k.min.y,k.max.x-k.min.x,k.max.y-k.min.y)}function k(a,b,c){return b>=a.x&&b<=a.x+a.width&&c>=a.y&&c<=a.y+a.height}function l(a,b){return a=d(a),b=d(b),k(b,a.x,a.y)||k(b,a.x2,a.y)||k(b,a.x,a.y2)||k(b,a.x2,a.y2)||k(a,b.x,b.y)||k(a,b.x2,b.y)||k(a,b.x,b.y2)||k(a,b.x2,b.y2)||(a.xb.x||b.xa.x)&&(a.yb.y||b.ya.y)}function m(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function n(a,b,c,d,e,f,g,h,i){null==i&&(i=1),i=i>1?1:0>i?0:i;for(var j=i/2,k=12,l=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;k>p;p++){var q=j*l[p]+j,r=m(q,a,c,e,g),s=m(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return j*o}function o(a,b,c,d,e,f,g,h,i){if(!(0>i||n(a,b,c,d,e,f,g,h)o;)l/=2,m+=(i>j?1:-1)*l,j=n(a,b,c,d,e,f,g,h,m);return m}}function p(a,b,c,d,e,f,g,h){if(!(Q(a,c)Q(e,g)||Q(b,d)Q(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+Q(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+Q(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+Q(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+Q(f,h).toFixed(2)))return{x:l,y:m}}}}function q(a,b,c){var d=j(a),e=j(b);if(!l(d,e))return c?0:[];for(var f=n.apply(0,a),g=n.apply(0,b),h=~~(f/5),k=~~(g/5),m=[],o=[],q={},r=c?0:[],s=0;h+1>s;s++){var t=i.apply(0,a.concat(s/h));m.push({x:t.x,y:t.y,t:s/h})}for(s=0;k+1>s;s++)t=i.apply(0,b.concat(s/k)),o.push({x:t.x,y:t.y,t:s/k});for(s=0;h>s;s++)for(var u=0;k>u;u++){var v=m[s],w=m[s+1],x=o[u],y=o[u+1],z=S(w.x-v.x)<.001?"y":"x",A=S(y.x-x.x)<.001?"y":"x",B=p(v.x,v.y,w.x,w.y,x.x,x.y,y.x,y.y);if(B){if(q[B.x.toFixed(4)]==B.y.toFixed(4))continue;q[B.x.toFixed(4)]=B.y.toFixed(4);var C=v.t+S((B[z]-v[z])/(w[z]-v[z]))*(w.t-v.t),D=x.t+S((B[A]-x[A])/(y[A]-x[A]))*(y.t-x.t);C>=0&&1>=C&&D>=0&&1>=D&&(c?r++:r.push({x:B.x,y:B.y,t1:C,t2:D}))}}return r}function r(a,b){return t(a,b)}function s(a,b){return t(a,b,1)}function t(a,b,c){a=E(a),b=E(b);for(var d,e,f,g,h,i,j,k,l,m,n=c?0:[],o=0,p=a.length;p>o;o++){var r=a[o];if("M"==r[0])d=h=r[1],e=i=r[2];else{"C"==r[0]?(l=[d,e].concat(r.slice(1)),d=l[6],e=l[7]):(l=[d,e,d,e,h,i,h,i],d=h,e=i);for(var s=0,t=b.length;t>s;s++){var u=b[s];if("M"==u[0])f=j=u[1],g=k=u[2];else{"C"==u[0]?(m=[f,g].concat(u.slice(1)),f=m[6],g=m[7]):(m=[f,g,f,g,j,k,j,k],f=j,g=k);var v=q(l,m,c);if(c)n+=v;else{for(var w=0,x=v.length;x>w;w++)v[w].segment1=o,v[w].segment2=s,v[w].bez1=l,v[w].bez2=m;n=n.concat(v)}}}}}return n}function u(a,b,c){var d=v(a);return k(d,b,c)&&1==t(a,[["M",b,c],["H",d.x2+10]],1)%2}function v(a){var b=c(a);if(b.bbox)return J(b.bbox);if(!a)return d();a=E(a);for(var e,f=0,g=0,h=[],i=[],j=0,k=a.length;k>j;j++)if(e=a[j],"M"==e[0])f=e[1],g=e[2],h.push(f),i.push(g);else{var l=D(f,g,e[1],e[2],e[3],e[4],e[5],e[6]);h=h.concat(l.min.x,l.max.x),i=i.concat(l.min.y,l.max.y),f=e[5],g=e[6]}var m=P.apply(0,h),n=P.apply(0,i),o=Q.apply(0,h),p=Q.apply(0,i),q=d(m,n,o-m,p-n);return b.bbox=J(q),q}function w(a,b,c,d,f){if(f)return[["M",+a+ +f,b],["l",c-2*f,0],["a",f,f,0,0,1,f,f],["l",0,d-2*f],["a",f,f,0,0,1,-f,f],["l",2*f-c,0],["a",f,f,0,0,1,-f,-f],["l",0,2*f-d],["a",f,f,0,0,1,f,-f],["z"]];var g=[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]];return g.toString=e,g}function x(a,b,c,d,f){if(null==f&&null==d&&(d=c),a=+a,b=+b,c=+c,d=+d,null!=f)var g=Math.PI/180,h=a+c*Math.cos(-d*g),i=a+c*Math.cos(-f*g),j=b+c*Math.sin(-d*g),k=b+c*Math.sin(-f*g),l=[["M",h,j],["A",c,c,0,+(f-d>180),0,i,k]];else l=[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]];return l.toString=e,l}function y(b){var d=c(b),g=String.prototype.toLowerCase;if(d.rel)return f(d.rel);a.is(b,"array")&&a.is(b&&b[0],"array")||(b=a.parsePathString(b));var h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=b[0][1],j=b[0][2],k=i,l=j,m++,h.push(["M",i,j]));for(var n=m,o=b.length;o>n;n++){var p=h[n]=[],q=b[n];if(q[0]!=g.call(q[0]))switch(p[0]=g.call(q[0]),p[0]){case"a":p[1]=q[1],p[2]=q[2],p[3]=q[3],p[4]=q[4],p[5]=q[5],p[6]=+(q[6]-i).toFixed(3),p[7]=+(q[7]-j).toFixed(3);break;case"v":p[1]=+(q[1]-j).toFixed(3);break;case"m":k=q[1],l=q[2];default:for(var r=1,s=q.length;s>r;r++)p[r]=+(q[r]-(r%2?i:j)).toFixed(3)}else{p=h[n]=[],"m"==q[0]&&(k=q[1]+i,l=q[2]+j);for(var t=0,u=q.length;u>t;t++)h[n][t]=q[t]}var v=h[n].length;switch(h[n][0]){case"z":i=k,j=l;break;case"h":i+=+h[n][v-1];break;case"v":j+=+h[n][v-1];break;default:i+=+h[n][v-2],j+=+h[n][v-1]}}return h.toString=e,d.rel=f(h),h}function z(b){var d=c(b);if(d.abs)return f(d.abs);if(I(b,"array")&&I(b&&b[0],"array")||(b=a.parsePathString(b)),!b||!b.length)return[["M",0,0]];var g,h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=+b[0][1],j=+b[0][2],k=i,l=j,m++,h[0]=["M",i,j]);for(var n,o,p=3==b.length&&"M"==b[0][0]&&"R"==b[1][0].toUpperCase()&&"Z"==b[2][0].toUpperCase(),q=m,r=b.length;r>q;q++){if(h.push(n=[]),o=b[q],g=o[0],g!=g.toUpperCase())switch(n[0]=g.toUpperCase(),n[0]){case"A":n[1]=o[1],n[2]=o[2],n[3]=o[3],n[4]=o[4],n[5]=o[5],n[6]=+o[6]+i,n[7]=+o[7]+j;break;case"V":n[1]=+o[1]+j;break;case"H":n[1]=+o[1]+i;break;case"R":for(var s=[i,j].concat(o.slice(1)),t=2,u=s.length;u>t;t++)s[t]=+s[t]+i,s[++t]=+s[t]+j;h.pop(),h=h.concat(G(s,p));break;case"O":h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);break;case"U":h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));break;case"M":k=+o[1]+i,l=+o[2]+j;default:for(t=1,u=o.length;u>t;t++)n[t]=+o[t]+(t%2?i:j)}else if("R"==g)s=[i,j].concat(o.slice(1)),h.pop(),h=h.concat(G(s,p)),n=["R"].concat(o.slice(-2));else if("O"==g)h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);else if("U"==g)h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));else for(var v=0,w=o.length;w>v;v++)n[v]=o[v];if(g=g.toUpperCase(),"O"!=g)switch(n[0]){case"Z":i=+k,j=+l;break;case"H":i=n[1];break;case"V":j=n[1];break;case"M":k=n[n.length-2],l=n[n.length-1];default:i=n[n.length-2],j=n[n.length-1]}}return h.toString=e,d.abs=f(h),h}function A(a,b,c,d){return[a,b,c,d,c,d]}function B(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]}function C(b,c,d,e,f,g,h,i,j,k){var l,m=120*O/180,n=O/180*(+f||0),o=[],p=a._.cacher(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(b,c,-n),b=l.x,c=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(O/180*f),N.sin(O/180*f),(b-i)/2),r=(c-j)/2,s=q*q/(d*d)+r*r/(e*e);s>1&&(s=N.sqrt(s),d=s*d,e=s*e);var t=d*d,u=e*e,v=(g==h?-1:1)*N.sqrt(S((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*d*r/e+(b+i)/2,x=v*-e*q/d+(c+j)/2,y=N.asin(((c-x)/e).toFixed(9)),z=N.asin(((j-x)/e).toFixed(9));y=w>b?O-y:y,z=w>i?O-z:z,0>y&&(y=2*O+y),0>z&&(z=2*O+z),h&&y>z&&(y-=2*O),!h&&z>y&&(z-=2*O)}var A=z-y;if(S(A)>m){var B=z,D=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+d*N.cos(z),j=x+e*N.sin(z),o=C(i,j,d,e,f,0,h,D,E,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),J=N.tan(A/4),K=4/3*d*J,L=4/3*e*J,M=[b,c],P=[b+K*G,c-L*F],Q=[i+K*I,j-L*H],R=[i,j];if(P[0]=2*M[0]-P[0],P[1]=2*M[1]-P[1],k)return[P,Q,R].concat(o);o=[P,Q,R].concat(o).join().split(",");for(var T=[],U=0,V=o.length;V>U;U++)T[U]=U%2?p(o[U-1],o[U],n).y:p(o[U],o[U+1],n).x;return T}function D(a,b,c,d,e,f,g,h){for(var i,j,k,l,m,n,o,p,q=[],r=[[],[]],s=0;2>s;++s)if(0==s?(j=6*a-12*c+6*e,i=-3*a+9*c-9*e+3*g,k=3*c-3*a):(j=6*b-12*d+6*f,i=-3*b+9*d-9*f+3*h,k=3*d-3*b),S(i)<1e-12){if(S(j)<1e-12)continue;l=-k/j,l>0&&1>l&&q.push(l)}else o=j*j-4*k*i,p=N.sqrt(o),0>o||(m=(-j+p)/(2*i),m>0&&1>m&&q.push(m),n=(-j-p)/(2*i),n>0&&1>n&&q.push(n));for(var t,u=q.length,v=u;u--;)l=q[u],t=1-l,r[0][u]=t*t*t*a+3*t*t*l*c+3*t*l*l*e+l*l*l*g,r[1][u]=t*t*t*b+3*t*t*l*d+3*t*l*l*f+l*l*l*h;return r[0][v]=a,r[1][v]=b,r[0][v+1]=g,r[1][v+1]=h,r[0].length=r[1].length=v+2,{min:{x:P.apply(0,r[0]),y:P.apply(0,r[1])},max:{x:Q.apply(0,r[0]),y:Q.apply(0,r[1])}}}function E(a,b){var d=!b&&c(a);if(!b&&d.curve)return f(d.curve);for(var e=z(a),g=b&&z(b),h={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},i={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},j=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"].concat(C.apply(0,[b.x,b.y].concat(a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e].concat(a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"].concat(B(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"].concat(B(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"].concat(A(b.x,b.y,a[1],a[2]));break;case"H":a=["C"].concat(A(b.x,b.y,a[1],b.y));break;case"V":a=["C"].concat(A(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"].concat(A(b.x,b.y,b.X,b.Y))}return a}),k=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)m[b]="A",g&&(n[b]="A"),a.splice(b++,0,["C"].concat(c.splice(0,6)));a.splice(b,1),r=Q(e.length,g&&g.length||0)}},l=function(a,b,c,d,f){a&&b&&"M"==a[f][0]&&"M"!=b[f][0]&&(b.splice(f,0,["M",d.x,d.y]),c.bx=0,c.by=0,c.x=a[f][1],c.y=a[f][2],r=Q(e.length,g&&g.length||0))},m=[],n=[],o="",p="",q=0,r=Q(e.length,g&&g.length||0);r>q;q++){e[q]&&(o=e[q][0]),"C"!=o&&(m[q]=o,q&&(p=m[q-1])),e[q]=j(e[q],h,p),"A"!=m[q]&&"C"==o&&(m[q]="C"),k(e,q),g&&(g[q]&&(o=g[q][0]),"C"!=o&&(n[q]=o,q&&(p=n[q-1])),g[q]=j(g[q],i,p),"A"!=n[q]&&"C"==o&&(n[q]="C"),k(g,q)),l(e,g,h,i,q),l(g,e,i,h,q);var s=e[q],t=g&&g[q],u=s.length,v=g&&t.length;h.x=s[u-2],h.y=s[u-1],h.bx=M(s[u-4])||h.x,h.by=M(s[u-3])||h.y,i.bx=g&&(M(t[v-4])||i.x),i.by=g&&(M(t[v-3])||i.y),i.x=g&&t[v-2],i.y=g&&t[v-1]}return g||(d.curve=f(e)),g?[e,g]:e}function F(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=E(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a}function G(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}var H=b.prototype,I=a.is,J=a._.clone,K="hasOwnProperty",L=/,?([a-z]),?/gi,M=parseFloat,N=Math,O=N.PI,P=N.min,Q=N.max,R=N.pow,S=N.abs,T=h(1),U=h(),V=h(0,1),W=a._unit2px,X={path:function(a){return a.attr("path")},circle:function(a){var b=W(a);return x(b.cx,b.cy,b.r)},ellipse:function(a){var b=W(a);return x(b.cx||0,b.cy||0,b.rx,b.ry)},rect:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height,b.rx,b.ry)},image:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height)},text:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)},g:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)},symbol:function(a){var b=a.getBBox();return w(b.x,b.y,b.width,b.height)},line:function(a){return"M"+[a.attr("x1")||0,a.attr("y1")||0,a.attr("x2"),a.attr("y2")]},polyline:function(a){return"M"+a.attr("points")},polygon:function(a){return"M"+a.attr("points")+"z"},svg:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)},deflt:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)}};a.path=c,a.path.getTotalLength=T,a.path.getPointAtLength=U,a.path.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return V(a,b).end;var d=V(a,c,1);return b?V(d,b).end:d},H.getTotalLength=function(){return this.node.getTotalLength?this.node.getTotalLength():void 0},H.getPointAtLength=function(a){return U(this.attr("d"),a)},H.getSubpath=function(b,c){return a.path.getSubpath(this.attr("d"),b,c)},a._.box=d,a.path.findDotsAtSegment=i,a.path.bezierBBox=j,a.path.isPointInsideBBox=k,a.path.isBBoxIntersect=l,a.path.intersection=r,a.path.intersectionNumber=s,a.path.isPointInside=u,a.path.getBBox=v,a.path.get=X,a.path.toRelative=y,a.path.toAbsolute=z,a.path.toCubic=E,a.path.map=F,a.path.toString=e,a.path.clone=f}),d.plugin(function(a){var d=Math.max,e=Math.min,f=function(a){if(this.items=[],this.length=0,this.type="set",a)for(var b=0,c=a.length;c>b;b++)a[b]&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},g=f.prototype;g.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],a&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},g.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},g.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this},g.animate=function(d,e,f,g){"function"!=typeof f||f.length||(g=f,f=c.linear),d instanceof a._.Animation&&(g=d.callback,f=d.easing,e=f.dur,d=d.attr);var h,i=function(){h?this.b=h:h=this.b},j=0,k=g&&function(){j++==this.length&&g.call(this)};return this.forEach(function(a){b.once("snap.animcreated."+a.id,i),a.animate(d,e,f,k)})},g.animateEach=function(){var a,c=0,d=this,e=function(){a?this.b=a:a=this.b},f=arguments,g=function(a){var f=d[c++];return f&&(f.animate.apply(f,arguments.length>1?arguments:a),b.once("snap.animcreated."+f.id,e)),d[c]?g:d};return g(f)},g.remove=function(){for(;this.length;)this.pop().remove();return this},g.attr=function(a){for(var b=0,c=this.items.length;c>b;b++)this.items[b].attr(a);return this},g.clear=function(){for(;this.length;)this.pop()},g.splice=function(a,b){a=0>a?d(this.length+a,0):a,b=d(0,e(this.length-a,b));var c,g=[],h=[],i=[];for(c=2;cc;c++)h.push(this[a+c]);for(;cc?i[c]:g[c-j];for(c=this.items.length=this.length-=b-j;this[c];)delete this[c++];return new f(h)},g.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0;return!1},g.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},g.getBBox=function(){for(var a=[],b=[],c=[],f=[],g=this.items.length;g--;)if(!this.items[g].removed){var h=this.items[g].getBBox();a.push(h.x),b.push(h.y),c.push(h.x+h.width),f.push(h.y+h.height)}return a=e.apply(0,a),b=e.apply(0,b),c=d.apply(0,c),f=d.apply(0,f),{x:a,y:b,x2:c,y2:f,width:c-a,height:f-b,cx:a+(c-a)/2,cy:b+(f-b)/2}},g.clone=function(a){a=new f;for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},g.toString=function(){return"Snap‘s set"},g.type="set",a.set=function(){var a=new f;return arguments.length&&a.push.apply(a,Array.prototype.slice.call(arguments,0)),a}}),d.plugin(function(a,b){function c(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}}function d(b,d,e){d=l(d).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],d=a.parseTransformString(d)||[];for(var f,g,j,k,m=Math.max(b.length,d.length),n=[],o=[],p=0;m>p;p++){if(j=b[p]||c(d[p]),k=d[p]||c(j),j[0]!=k[0]||"r"==j[0].toLowerCase()&&(j[2]!=k[2]||j[3]!=k[3])||"s"==j[0].toLowerCase()&&(j[3]!=k[3]||j[4]!=k[4])){b=a._.transform2matrix(b,e()),d=a._.transform2matrix(d,e()),n=[["m",b.a,b.b,b.c,b.d,b.e,b.f]],o=[["m",d.a,d.b,d.c,d.d,d.e,d.f]];break}for(n[p]=[],o[p]=[],f=0,g=Math.max(j.length,k.length);g>f;f++)f in j&&(n[p][f]=j[f]),f in k&&(o[p][f]=k[f])}return{from:i(n),to:i(o),f:h(n)}}function e(a){return a}function f(a){return function(b){return+b.toFixed(3)+a}}function g(b){return a.rgb(b[0],b[1],b[2])}function h(a){var b,c,d,e,f,g,h=0,i=[];for(b=0,c=a.length;c>b;b++){for(f="[",g=['"'+a[b][0]+'"'],d=1,e=a[b].length;e>d;d++)g[d]="val["+h++ +"]";f+=g+"]",i[b]=f}return Function("val","return Snap.path.toString.call(["+i+"])")}function i(a){for(var b=[],c=0,d=a.length;d>c;c++)for(var e=1,f=a[c].length;f>e;e++)b.push(a[c][e]);return b}var j={},k=/[a-z]+$/i,l=String;j.stroke=j.fill="colour",b.prototype.equal=function(b,c){var m,n,o=l(this.attr(b)||""),p=this;if(o==+o&&c==+c)return{from:+o,to:+c,f:e};if("colour"==j[b])return m=a.color(o),n=a.color(c),{from:[m.r,m.g,m.b,m.opacity],to:[n.r,n.g,n.b,n.opacity],f:g};if("transform"==b||"gradientTransform"==b||"patternTransform"==b)return c instanceof a.Matrix&&(c=c.toTransformString()),a._.rgTransform.test(c)||(c=a._.svgTransform2string(c)),d(o,c,function(){return p.getBBox(1)});if("d"==b||"path"==b)return m=a.path.toCubic(o,c),{from:i(m[0]),to:i(m[1]),f:h(m[0])};if("points"==b)return m=l(o).split(","),n=l(c).split(","),{from:m,to:n,f:function(a){return a}};var q=o.match(k),r=l(c).match(k);return q&&q==r?{from:parseFloat(o),to:parseFloat(c),f:f(q)}:{from:this.asPX(b),to:this.asPX(b,c),f:e}}}),d.plugin(function(a,c,d,e){for(var f=c.prototype,g="hasOwnProperty",h=("createTouch"in e.doc),i=["click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup","touchstart","touchmove","touchend","touchcancel"],j={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},k=function(a){var b="y"==a?"scrollTop":"scrollLeft";return e.doc.documentElement[b]||e.doc.body[b]},l=function(){this.returnValue=!1},m=function(){return this.originalEvent.preventDefault()},n=function(){this.cancelBubble=!0},o=function(){return this.originalEvent.stopPropagation()},p=function(){return e.doc.addEventListener?function(a,b,c,d){var e=h&&j[b]?j[b]:b,f=function(e){var f=k("y"),i=k("x");if(h&&j[g](b))for(var l=0,n=e.targetTouches&&e.targetTouches.length;n>l;l++)if(e.targetTouches[l].target==a||a.contains(e.targetTouches[l].target)){var p=e;e=e.targetTouches[l],e.originalEvent=p,e.preventDefault=m,e.stopPropagation=o;break}var q=e.clientX+i,r=e.clientY+f;return c.call(d,e,q,r)};return b!==e&&a.addEventListener(b,f,!1),a.addEventListener(e,f,!1),function(){return b!==e&&a.removeEventListener(b,f,!1),a.removeEventListener(e,f,!1),!0}}:e.doc.attachEvent?function(a,b,c,d){var f=function(a){a=a||e.win.event;var b=k("y"),f=k("x"),g=a.clientX+f,h=a.clientY+b;return a.preventDefault=a.preventDefault||l,a.stopPropagation=a.stopPropagation||n,c.call(d,a,g,h) -};a.attachEvent("on"+b,f);var g=function(){return a.detachEvent("on"+b,f),!0};return g}:void 0}(),q=[],r=function(c){for(var d,e=c.clientX,f=c.clientY,g=k("y"),i=k("x"),j=q.length;j--;){if(d=q[j],h){for(var l,m=c.touches&&c.touches.length;m--;)if(l=c.touches[m],l.identifier==d.el._drag.id||d.el.node.contains(l.target)){e=l.clientX,f=l.clientY,(c.originalEvent?c.originalEvent:c).preventDefault();break}}else c.preventDefault();var n=d.el.node;a._.glob,n.nextSibling,n.parentNode,n.style.display,e+=i,f+=g,b("snap.drag.move."+d.el.id,d.move_scope||d.el,e-d.el._drag.x,f-d.el._drag.y,e,f,c)}},s=function(c){a.unmousemove(r).unmouseup(s);for(var d,e=q.length;e--;)d=q[e],d.el._drag={},b("snap.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c);q=[]},t=i.length;t--;)!function(b){a[b]=f[b]=function(c,d){return a.is(c,"function")&&(this.events=this.events||[],this.events.push({name:b,f:c,unbind:p(this.shape||this.node||e.doc,b,c,d||this)})),this},a["un"+b]=f["un"+b]=function(a){for(var c=this.events||[],d=c.length;d--;)if(c[d].name==b&&(c[d].f==a||!a))return c[d].unbind(),c.splice(d,1),!c.length&&delete this.events,this;return this}}(i[t]);f.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},f.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var u=[];f.drag=function(c,d,e,f,g,h){function i(i,j,k){(i.originalEvent||i).preventDefault(),this._drag.x=j,this._drag.y=k,this._drag.id=i.identifier,!q.length&&a.mousemove(r).mouseup(s),q.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("snap.drag.start."+this.id,d),c&&b.on("snap.drag.move."+this.id,c),e&&b.on("snap.drag.end."+this.id,e),b("snap.drag.start."+this.id,g||f||this,j,k,i)}if(!arguments.length){var j;return this.drag(function(a,b){this.attr({transform:j+(j?"T":"t")+[a,b]})},function(){j=this.transform().local})}return this._drag={},u.push({el:this,start:i}),this.mousedown(i),this},f.undrag=function(){for(var c=u.length;c--;)u[c].el==this&&(this.unmousedown(u[c].start),u.splice(c,1),b.unbind("snap.drag.*."+this.id));return!u.length&&a.unmousemove(r).unmouseup(s),this}}),d.plugin(function(a,c,d){var e=(c.prototype,d.prototype),f=/^\s*url\((.+)\)/,g=String,h=a._.$;a.filter={},e.filter=function(b){var d=this;"svg"!=d.type&&(d=d.paper);var e=a.parse(g(b)),f=a._.id(),i=(d.node.offsetWidth,d.node.offsetHeight,h("filter"));return h(i,{id:f,filterUnits:"userSpaceOnUse"}),i.appendChild(e.node),d.defs.appendChild(i),new c(i)},b.on("snap.util.getattr.filter",function(){b.stop();var c=h(this.node,"filter");if(c){var d=g(c).match(f);return d&&a.select(d[1])}}),b.on("snap.util.attr.filter",function(d){if(d instanceof c&&"filter"==d.type){b.stop();var e=d.node.id;e||(h(d.node,{id:d.id}),e=d.id),h(this.node,{filter:a.url(e)})}d&&"none"!=d||(b.stop(),this.node.removeAttribute("filter"))}),a.filter.blur=function(b,c){null==b&&(b=2);var d=null==c?b:[b,c];return a.format('',{def:d})},a.filter.blur.toString=function(){return this()},a.filter.shadow=function(b,c,d,e,f){return"string"==typeof d&&(e=d,f=e,d=4),"string"!=typeof e&&(f=e,e="#000"),e=e||"#000",null==d&&(d=4),null==f&&(f=1),null==b&&(b=0,c=2),null==c&&(c=b),e=a.color(e),a.format('',{color:e,dx:b,dy:c,blur:d,opacity:f})},a.filter.shadow.toString=function(){return this()},a.filter.grayscale=function(b){return null==b&&(b=1),a.format('',{a:.2126+.7874*(1-b),b:.7152-.7152*(1-b),c:.0722-.0722*(1-b),d:.2126-.2126*(1-b),e:.7152+.2848*(1-b),f:.0722-.0722*(1-b),g:.2126-.2126*(1-b),h:.0722+.9278*(1-b)})},a.filter.grayscale.toString=function(){return this()},a.filter.sepia=function(b){return null==b&&(b=1),a.format('',{a:.393+.607*(1-b),b:.769-.769*(1-b),c:.189-.189*(1-b),d:.349-.349*(1-b),e:.686+.314*(1-b),f:.168-.168*(1-b),g:.272-.272*(1-b),h:.534-.534*(1-b),i:.131+.869*(1-b)})},a.filter.sepia.toString=function(){return this()},a.filter.saturate=function(b){return null==b&&(b=1),a.format('',{amount:1-b})},a.filter.saturate.toString=function(){return this()},a.filter.hueRotate=function(b){return b=b||0,a.format('',{angle:b})},a.filter.hueRotate.toString=function(){return this()},a.filter.invert=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:1-b})},a.filter.invert.toString=function(){return this()},a.filter.brightness=function(b){return null==b&&(b=1),a.format('',{amount:b})},a.filter.brightness.toString=function(){return this()},a.filter.contrast=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:.5-b/2})},a.filter.contrast.toString=function(){return this()}}),d}); \ No newline at end of file +// build: 2014-05-07 +!function(a){var b,c,d="0.4.2",e="hasOwnProperty",f=/[\.\/]/,g="*",h=function(){},i=function(a,b){return a-b},j={n:{}},k=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=k.listeners(a),j=0,l=[],m={},n=[],o=b;b=a,c=0;for(var p=0,q=h.length;q>p;p++)"zIndex"in h[p]&&(l.push(h[p].zIndex),h[p].zIndex<0&&(m[h[p].zIndex]=h[p]));for(l.sort(i);l[j]<0;)if(e=m[l[j++]],n.push(e.apply(d,g)),c)return c=f,n;for(p=0;q>p;p++)if(e=h[p],"zIndex"in e)if(e.zIndex==l[j]){if(n.push(e.apply(d,g)),c)break;do if(j++,e=m[l[j]],e&&n.push(e.apply(d,g)),c)break;while(e)}else m[e.zIndex]=e;else if(n.push(e.apply(d,g)),c)break;return c=f,b=o,n.length?n:null};k._events=j,k.listeners=function(a){var b,c,d,e,h,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,h=m.length;h>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[g]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},k.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(f),d=j,e=0,g=c.length;g>e;e++)d=d.n,d=d.hasOwnProperty(c[e])&&d[c[e]]||(d[c[e]]={n:{}});for(d.f=d.f||[],e=0,g=d.f.length;g>e;e++)if(d.f[e]==b)return h;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},k.f=function(a){var b=[].slice.call(arguments,1);return function(){k.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},k.stop=function(){c=1},k.nt=function(a){return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(b):b},k.nts=function(){return b.split(f)},k.off=k.unbind=function(a,b){if(!a)return void(k._events=j={n:{}});var c,d,h,i,l,m,n,o=a.split(f),p=[j];for(i=0,l=o.length;l>i;i++)for(m=0;mi;i++)for(c=p[i];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++)if(c.f[m]==b){c.f.splice(m,1);break}!c.f.length&&delete c.f}for(d in c.n)if(c.n[e](d)&&c.n[d].f){var q=c.n[d].f;for(m=0,n=q.length;n>m;m++)if(q[m]==b){q.splice(m,1);break}!q.length&&delete c.n[d].f}}else{delete c.f;for(d in c.n)c.n[e](d)&&c.n[d].f&&delete c.n[d].f}c=c.n}},k.once=function(a,b){var c=function(){return k.unbind(a,c),b.apply(this,arguments)};return k.on(a,c)},k.version=d,k.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=k:"undefined"!=typeof define?define("eve",[],function(){return k}):a.eve=k}(this),function(a,b){"function"==typeof define&&define.amd?define(["eve"],function(c){return b(a,c)}):b(a,a.eve)}(this,function(a,b){var c=function(b){var c={},d=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},e=Array.isArray||function(a){return a instanceof Array||"[object Array]"==Object.prototype.toString.call(a)},f=0,g="M"+(+new Date).toString(36),h=function(){return g+(f++).toString(36)},i=Date.now||function(){return+new Date},j=function(a){var b=this;if(null==a)return b.s;var c=b.s-a;b.b+=b.dur*c,b.B+=b.dur*c,b.s=a},k=function(a){var b=this;return null==a?b.spd:void(b.spd=a)},l=function(a){var b=this;return null==a?b.dur:(b.s=b.s*a/b.dur,void(b.dur=a))},m=function(){var a=this;delete c[a.id],a.update(),b("mina.stop."+a.id,a)},n=function(){var a=this;a.pdif||(delete c[a.id],a.update(),a.pdif=a.get()-a.b)},o=function(){var a=this;a.pdif&&(a.b=a.get()-a.pdif,delete a.pdif,c[a.id]=a)},p=function(){var a,b=this;if(e(b.start)){a=[];for(var c=0,d=b.start.length;d>c;c++)a[c]=+b.start[c]+(b.end[c]-b.start[c])*b.easing(b.s)}else a=+b.start+(b.end-b.start)*b.easing(b.s);b.set(a)},q=function(){var a=0;for(var e in c)if(c.hasOwnProperty(e)){var f=c[e],g=f.get();a++,f.s=(g-f.b)/(f.dur/f.spd),f.s>=1&&(delete c[e],f.s=1,a--,function(a){setTimeout(function(){b("mina.finish."+a.id,a)})}(f)),f.update()}a&&d(q)},r=function(a,b,e,f,g,i,s){var t={id:h(),start:a,end:b,b:e,s:0,dur:f-e,spd:1,get:g,set:i,easing:s||r.linear,status:j,speed:k,duration:l,stop:m,pause:n,resume:o,update:p};c[t.id]=t;var u,v=0;for(u in c)if(c.hasOwnProperty(u)&&(v++,2==v))break;return 1==v&&d(q),t};return r.time=i,r.getById=function(a){return c[a]||null},r.linear=function(a){return a},r.easeout=function(a){return Math.pow(a,1.7)},r.easein=function(a){return Math.pow(a,.48)},r.easeinout=function(a){if(1==a)return 1;if(0==a)return 0;var b=.48-a/1.04,c=Math.sqrt(.1734+b*b),d=c-b,e=Math.pow(Math.abs(d),1/3)*(0>d?-1:1),f=-c-b,g=Math.pow(Math.abs(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},r.backin=function(a){if(1==a)return 1;var b=1.70158;return a*a*((b+1)*a-b)},r.backout=function(a){if(0==a)return 0;a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},r.elastic=function(a){return a==!!a?a:Math.pow(2,-10*a)*Math.sin(2*(a-.075)*Math.PI/.3)+1},r.bounce=function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b},a.mina=r,r}("undefined"==typeof b?function(){}:b),d=function(){function d(a,b){if(a){if(a.tagName)return y(a);if(f(a,"array")&&d.set)return d.set.apply(d,a);if(a instanceof t)return a;if(null==b)return a=z.doc.querySelector(a),y(a)}return a=null==a?"100%":a,b=null==b?"100%":b,new x(a,b)}function e(a,b){if(b){if("#text"==a&&(a=z.doc.createTextNode(b.text||"")),"string"==typeof a&&(a=e(a)),"string"==typeof b)return"xlink:"==b.substring(0,6)?a.getAttributeNS(W,b.substring(6)):"xml:"==b.substring(0,4)?a.getAttributeNS(X,b.substring(4)):a.getAttribute(b);for(var c in b)if(b[A](c)){var d=B(b[c]);d?"xlink:"==c.substring(0,6)?a.setAttributeNS(W,c.substring(6),d):"xml:"==c.substring(0,4)?a.setAttributeNS(X,c.substring(4),d):a.setAttribute(c,d):a.removeAttribute(c)}}else a=z.doc.createElementNS(X,a);return a}function f(a,b){return b=B.prototype.toLowerCase.call(b),"finite"==b?isFinite(a):"array"==b&&(a instanceof Array||Array.isArray&&Array.isArray(a))?!0:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||L.call(a).slice(8,-1).toLowerCase()==b}function h(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[A](c)&&(b[c]=h(a[c]));return b}function i(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function j(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),g=d.cache=d.cache||{},h=d.count=d.count||[];return g[A](f)?(i(h,f),c?c(g[f]):g[f]):(h.length>=1e3&&delete g[h.shift()],h.push(f),g[f]=a.apply(b,e),c?c(g[f]):g[f])}return d}function k(a,b,c,d,e,f){if(null==e){var g=a-c,h=b-d;return g||h?(180+180*E.atan2(-h,-g)/I+360)%360:0}return k(a,b,e,f)-k(c,d,e,f)}function l(a){return a%360*I/180}function m(a){return 180*a/I%360}function n(a){var b=[];return a=a.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g,function(a,c,d){return d=d.split(/\s*,\s*|\s+/),"rotate"==c&&1==d.length&&d.push(0,0),"scale"==c&&(d.length>2?d=d.slice(0,2):2==d.length&&d.push(0,0),1==d.length&&d.push(d[0],0,0)),b.push("skewX"==c?["m",1,0,E.tan(l(d[0])),1,0,0]:"skewY"==c?["m",1,E.tan(l(d[0])),0,1,0,0]:[c.charAt(0)].concat(d)),a}),b}function o(a,b){var c=eb(a),e=new d.Matrix;if(c)for(var f=0,g=c.length;g>f;f++){var h,i,j,k,l,m=c[f],n=m.length,o=B(m[0]).toLowerCase(),p=m[0]!=o,q=p?e.invert():0;"t"==o&&2==n?e.translate(m[1],0):"t"==o&&3==n?p?(h=q.x(0,0),i=q.y(0,0),j=q.x(m[1],m[2]),k=q.y(m[1],m[2]),e.translate(j-h,k-i)):e.translate(m[1],m[2]):"r"==o?2==n?(l=l||b,e.rotate(m[1],l.x+l.width/2,l.y+l.height/2)):4==n&&(p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.rotate(m[1],j,k)):e.rotate(m[1],m[2],m[3])):"s"==o?2==n||3==n?(l=l||b,e.scale(m[1],m[n-1],l.x+l.width/2,l.y+l.height/2)):4==n?p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.scale(m[1],m[1],j,k)):e.scale(m[1],m[1],m[2],m[3]):5==n&&(p?(j=q.x(m[3],m[4]),k=q.y(m[3],m[4]),e.scale(m[1],m[2],j,k)):e.scale(m[1],m[2],m[3],m[4])):"m"==o&&7==n&&e.add(m[1],m[2],m[3],m[4],m[5],m[6])}return e}function p(a,b){if(null==b){var c=!0;if(b=a.node.getAttribute("linearGradient"==a.type||"radialGradient"==a.type?"gradientTransform":"pattern"==a.type?"patternTransform":"transform"),!b)return new d.Matrix;b=n(b)}else b=d._.rgTransform.test(b)?B(b).replace(/\.{3}|\u2026/g,a._.transform||J):n(b),f(b,"array")&&(b=d.path?d.path.toString.call(b):B(b)),a._.transform=b;var e=o(b,a.getBBox(1));return c?e:void(a.matrix=e)}function q(a){var b=a.node.ownerSVGElement&&y(a.node.ownerSVGElement)||a.node.parentNode&&y(a.node.parentNode)||d.select("svg")||d(0,0),c=b.select("defs"),e=null==c?!1:c.node;return e||(e=w("defs",b.node).node),e}function r(a,b,c){function d(a){return null==a?J:a==+a?a:(e(j,{width:a}),j.getBBox().width)}function f(a){return null==a?J:a==+a?a:(e(j,{height:a}),j.getBBox().height)}function g(d,e){null==b?i[d]=e(a.attr(d)||0):d==b&&(i=e(null==c?a.attr(d)||0:c))}var h=q(a),i={},j=h.querySelector(".svg---mgr");switch(j||(j=e("rect"),e(j,{width:10,height:10,"class":"svg---mgr"}),h.appendChild(j)),a.type){case"rect":g("rx",d),g("ry",f);case"image":g("width",d),g("height",f);case"text":g("x",d),g("y",f);break;case"circle":g("cx",d),g("cy",f),g("r",d);break;case"ellipse":g("cx",d),g("cy",f),g("rx",d),g("ry",f);break;case"line":g("x1",d),g("x2",d),g("y1",f),g("y2",f);break;case"marker":g("refX",d),g("markerWidth",d),g("refY",f),g("markerHeight",f);break;case"radialGradient":g("fx",d),g("fy",f);break;case"tspan":g("dx",d),g("dy",f);break;default:g(b,d)}return i}function s(a){f(a,"array")||(a=Array.prototype.slice.call(arguments,0));for(var b=0,c=0,d=this.node;this[b];)delete this[b++];for(b=0;bc;c++)if(b=b||a[c])return b}function v(a){this.node=a}function w(a,b){var c=e(a);b.appendChild(c);var d=y(c);return d}function x(a,b){var c,d,f,g=x.prototype;if(a&&"svg"==a.tagName){if(a.snap in Y)return Y[a.snap];var h=a.ownerDocument;c=new t(a),d=a.getElementsByTagName("desc")[0],f=a.getElementsByTagName("defs")[0],d||(d=e("desc"),d.appendChild(h.createTextNode("Created with Snap")),c.node.appendChild(d)),f||(f=e("defs"),c.node.appendChild(f)),c.defs=f;for(var i in g)g[A](i)&&(c[i]=g[i]);c.paper=c.root=c}else c=w("svg",z.doc.body),e(c.node,{height:b,version:1.1,width:a,xmlns:X});return c}function y(a){return a?a instanceof t||a instanceof v?a:a.tagName&&"svg"==a.tagName.toLowerCase()?new x(a):a.tagName&&"object"==a.tagName.toLowerCase()&&"image/svg+xml"==a.type?new x(a.contentDocument.getElementsByTagName("svg")[0]):new t(a):a}d.version="0.3.0",d.toString=function(){return"Snap v"+this.version},d._={};var z={win:a,doc:a.document};d._.glob=z;var A="hasOwnProperty",B=String,C=parseFloat,D=parseInt,E=Math,F=E.max,G=E.min,H=E.abs,I=(E.pow,E.PI),J=(E.round,""),K=" ",L=Object.prototype.toString,M=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,N=" \n \f\r   ᠎              \u2028\u2029",O=(d._.separator=new RegExp("[,"+N+"]+"),new RegExp("["+N+"]","g"),new RegExp("["+N+"]*,["+N+"]*")),P={hs:1,rg:1},Q=new RegExp("([a-z])["+N+",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?["+N+"]*,?["+N+"]*)+)","ig"),R=new RegExp("([rstm])["+N+",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?["+N+"]*,?["+N+"]*)+)","ig"),S=new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)["+N+"]*,?["+N+"]*","ig"),T=0,U="S"+(+new Date).toString(36),V=function(){return U+(T++).toString(36)},W="http://www.w3.org/1999/xlink",X="http://www.w3.org/2000/svg",Y={},Z=d.url=function(a){return"url('#"+a+"')"};d._.$=e,d._.id=V,d.format=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return B(b).replace(a,function(a,b){return c(a,b,d)})}}(),d._.clone=h,d._.cacher=j,d.rad=l,d.deg=m,d.angle=k,d.is=f,d.snapTo=function(a,b,c){if(c=f(c,"finite")?c:10,f(a,"array")){for(var d=a.length;d--;)if(H(a[d]-b)<=c)return a[d]}else{a=+a;var e=b%a;if(c>e)return b-e;if(e>a-c)return b-e+a}return b},d.getRGB=j(function(a){if(!a||(a=B(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bb};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:bb};if(!(P[A](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=$(a)),!a)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bb};var b,c,e,g,h,i,j=a.match(M);return j?(j[2]&&(e=D(j[2].substring(5),16),c=D(j[2].substring(3,5),16),b=D(j[2].substring(1,3),16)),j[3]&&(e=D((h=j[3].charAt(3))+h,16),c=D((h=j[3].charAt(2))+h,16),b=D((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4].split(O),b=C(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),c=C(i[1]),"%"==i[1].slice(-1)&&(c*=2.55),e=C(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=C(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5].split(O),b=C(i[0]),"%"==i[0].slice(-1)&&(b/=100),c=C(i[1]),"%"==i[1].slice(-1)&&(c/=100),e=C(i[2]),"%"==i[2].slice(-1)&&(e/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=C(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),d.hsb2rgb(b,c,e,g)):j[6]?(i=j[6].split(O),b=C(i[0]),"%"==i[0].slice(-1)&&(b/=100),c=C(i[1]),"%"==i[1].slice(-1)&&(c/=100),e=C(i[2]),"%"==i[2].slice(-1)&&(e/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=C(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),d.hsl2rgb(b,c,e,g)):(b=G(E.round(b),255),c=G(E.round(c),255),e=G(E.round(e),255),g=G(F(g,0),1),j={r:b,g:c,b:e,toString:bb},j.hex="#"+(16777216|e|c<<8|b<<16).toString(16).slice(1),j.opacity=f(g,"finite")?g:1,j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bb}},d),d.hsb=j(function(a,b,c){return d.hsb2rgb(a,b,c).hex}),d.hsl=j(function(a,b,c){return d.hsl2rgb(a,b,c).hex}),d.rgb=j(function(a,b,c,d){if(f(d,"finite")){var e=E.round;return"rgba("+[e(a),e(b),e(c),+d.toFixed(2)]+")"}return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)});var $=function(a){var b=z.doc.getElementsByTagName("head")[0],c="rgb(255, 0, 0)";return($=j(function(a){if("red"==a.toLowerCase())return c;b.style.color=c,b.style.color=a;var d=z.doc.defaultView.getComputedStyle(b,J).getPropertyValue("color");return d==c?null:d}))(a)},_=function(){return"hsb("+[this.h,this.s,this.b]+")"},ab=function(){return"hsl("+[this.h,this.s,this.l]+")"},bb=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},cb=function(a,b,c){if(null==b&&f(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(c=a.b,b=a.g,a=a.r),null==b&&f(a,string)){var e=d.getRGB(a);a=e.r,b=e.g,c=e.b}return(a>1||b>1||c>1)&&(a/=255,b/=255,c/=255),[a,b,c]},db=function(a,b,c,e){a=E.round(255*a),b=E.round(255*b),c=E.round(255*c);var g={r:a,g:b,b:c,opacity:f(e,"finite")?e:1,hex:d.rgb(a,b,c),toString:bb};return f(e,"finite")&&(g.opacity=e),g};d.color=function(a){var b;return f(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=d.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):f(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=d.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):(f(a,"string")&&(a=d.getRGB(a)),f(a,"object")&&"r"in a&&"g"in a&&"b"in a&&!("error"in a)?(b=d.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=d.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1,a.error=1)),a.toString=bb,a},d.hsb2rgb=function(a,b,c,d){f(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,g,h,i,j;return a=a%360/60,j=c*b,i=j*(1-H(a%2-1)),e=g=h=c-j,a=~~a,e+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],db(e,g,h,d)},d.hsl2rgb=function(a,b,c,d){f(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,g,h,i,j;return a=a%360/60,j=2*b*(.5>c?c:1-c),i=j*(1-H(a%2-1)),e=g=h=c-j/2,a=~~a,e+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],db(e,g,h,d)},d.rgb2hsb=function(a,b,c){c=cb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=F(a,b,c),g=f-G(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:_}},d.rgb2hsl=function(a,b,c){c=cb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=F(a,b,c),h=G(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:ab}},d.parsePathString=function(a){if(!a)return null;var b=d.path(a);if(b.arr)return d.path.clone(b.arr);var c={a:7,c:6,o:2,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,u:3,z:0},e=[];return f(a,"array")&&f(a[0],"array")&&(e=d.path.clone(a)),e.length||B(a).replace(Q,function(a,b,d){var f=[],g=b.toLowerCase();if(d.replace(S,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b].concat(f.splice(0,2))),g="l",b="m"==b?"l":"L"),"o"==g&&1==f.length&&e.push([b,f[0]]),"r"==g)e.push([b].concat(f));else for(;f.length>=c[g]&&(e.push([b].concat(f.splice(0,c[g]))),c[g]););}),e.toString=d.path.toString,b.arr=d.path.clone(e),e};var eb=d.parseTransformString=function(a){if(!a)return null;var b=[];return f(a,"array")&&f(a[0],"array")&&(b=d.path.clone(a)),b.length||B(a).replace(R,function(a,c,d){{var e=[];c.toLowerCase()}d.replace(S,function(a,b){b&&e.push(+b)}),b.push([c].concat(e))}),b.toString=d.path.toString,b};d._.svgTransform2string=n,d._.rgTransform=new RegExp("^[a-z]["+N+"]*-?\\.?\\d","i"),d._.transform2matrix=o,d._unit2px=r;z.doc.contains||z.doc.compareDocumentPosition?function(a,b){var c=9==a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a==d||!(!d||1!=d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b;)if(b=b.parentNode,b==a)return!0;return!1};d._.getSomeDefs=q,d.select=function(a){return y(z.doc.querySelector(a))},d.selectAll=function(a){for(var b=z.doc.querySelectorAll(a),c=(d.set||Array)(),e=0;ej;j++){d=f[j],b(d,"fill"),b(d,"stroke"),b(d,"filter"),b(d,"mask"),b(d,"clip-path"),c(d);var l=e(d.node,"id");l&&(e(d.node,{id:d.id}),h.push({old:l,id:d.id}))}for(j=0,k=h.length;k>j;j++){var m=i[h[j].old];if(m)for(var n=0,o=m.length;o>n;n++)m[n](h[j].id)}}function h(a,b,c){return function(d){var e=d.slice(a,b);return 1==e.length&&(e=e[0]),c?c(e):e}}function i(a){return function(){var b=a?"<"+this.type:"",c=this.node.attributes,d=this.node.childNodes;if(a)for(var e=0,f=c.length;f>e;e++)b+=" "+c[e].name+'="'+c[e].value.replace(/"/g,'\\"')+'"';if(d.length){for(a&&(b+=">"),e=0,f=d.length;f>e;e++)3==d[e].nodeType?b+=d[e].nodeValue:1==d[e].nodeType&&(b+=y(d[e]).toString());a&&(b+="")}else a&&(b+="/>");return b}}a.attr=function(a,c){{var d=this;d.node}if(!a)return d;if(f(a,"string")){if(!(arguments.length>1))return u(b("snap.util.getattr."+a,d));var e={};e[a]=c,a=e}for(var g in a)a[A](g)&&b("snap.util.attr."+g,d,a[g]);return d},a.getBBox=function(a){var b=this;if(b.removed)return{};if("use"==b.type)if(b.original)b=b.original;else{var c=b.attr("xlink:href");b=b.node.ownerDocument.getElementById(c.substring(c.indexOf("#")+1))}var e=b._;return a?(e.bboxwt=d.path.get[b.type]?d.path.getBBox(b.realPath=d.path.get[b.type](b)):d._.box(b.node.getBBox()),d._.box(e.bboxwt)):(b.realPath=(d.path.get[b.type]||d.path.get.deflt)(b),b.matrix=b.transform().localMatrix,e.bbox=d.path.getBBox(d.path.map(b.realPath,b.matrix)),d._.box(e.bbox))};var j=function(){return this.string};a.transform=function(a){var b=this._;if(null==a){for(var c,f=this,g=new d.Matrix(this.node.getCTM()),h=p(this),i=[h],k=new d.Matrix,l=h.toTransformString(),m=B(h)==B(this.matrix)?b.transform:l;"svg"!=f.type&&(f=f.parent());)i.push(p(f));for(c=i.length;c--;)k.add(i[c]);return{string:m,globalMatrix:g,totalMatrix:k,localMatrix:h,diffMatrix:g.clone().add(h.invert()),global:g.toTransformString(),total:k.toTransformString(),local:l,toString:j}}return a instanceof d.Matrix?this.matrix=a:p(this,a),this.node&&("linearGradient"==this.type||"radialGradient"==this.type?e(this.node,{gradientTransform:this.matrix}):"pattern"==this.type?e(this.node,{patternTransform:this.matrix}):e(this.node,{transform:this.matrix})),this},a.parent=function(){return y(this.node.parentNode)},a.append=a.add=function(a){if(a){if("set"==a.type){var b=this;return a.forEach(function(a){b.add(a)}),this}a=y(a),this.node.appendChild(a.node),a.paper=this.paper}return this},a.appendTo=function(a){return a&&(a=y(a),a.append(this)),this},a.prepend=function(a){if(a){a=y(a);var b=a.parent();this.node.insertBefore(a.node,this.node.firstChild),this.add&&this.add(),a.paper=this.paper,this.parent()&&this.parent().add(),b&&b.add()}return this},a.prependTo=function(a){return a=y(a),a.prepend(this),this},a.before=function(a){if("set"==a.type){var b=this;return a.forEach(function(a){var c=a.parent();b.node.parentNode.insertBefore(a.node,b.node),c&&c.add()}),this.parent().add(),this}a=y(a);var c=a.parent();return this.node.parentNode.insertBefore(a.node,this.node),this.parent()&&this.parent().add(),c&&c.add(),a.paper=this.paper,this},a.after=function(a){a=y(a);var b=a.parent();return this.node.nextSibling?this.node.parentNode.insertBefore(a.node,this.node.nextSibling):this.node.parentNode.appendChild(a.node),this.parent()&&this.parent().add(),b&&b.add(),a.paper=this.paper,this},a.insertBefore=function(a){a=y(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},a.insertAfter=function(a){a=y(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node.nextSibling),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},a.remove=function(){var a=this.parent();return this.node.parentNode&&this.node.parentNode.removeChild(this.node),delete this.paper,this.removed=!0,a&&a.add(),this},a.select=function(a){return y(this.node.querySelector(a))},a.selectAll=function(a){for(var b=this.node.querySelectorAll(a),c=(d.set||Array)(),e=0;eb;b++)a[b].stop();return this},a.animate=function(a,d,e,g){"function"!=typeof e||e.length||(g=e,e=c.linear),a instanceof l&&(g=a.callback,e=a.easing,d=e.dur,a=a.attr);var i,j,k,m,n=[],o=[],p={},q=this;for(var r in a)if(a[A](r)){q.equal?(m=q.equal(r,B(a[r])),i=m.from,j=m.to,k=m.f):(i=+q.attr(r),j=+a[r]);var s=f(i,"array")?i.length:1;p[r]=h(n.length,n.length+s,k),n=n.concat(i),o=o.concat(j)}var t=c.time(),u=c(n,o,t,t+d,c.time,function(a){var b={};for(var c in p)p[A](c)&&(b[c]=p[c](a));q.attr(b)},e);return q.anims[u.id]=u,u._attrs=a,u._callback=g,b("snap.animcreated."+q.id,u),b.once("mina.finish."+u.id,function(){delete q.anims[u.id],g&&g.call(q)}),b.once("mina.stop."+u.id,function(){delete q.anims[u.id]}),q};var m={};a.data=function(a,c){var e=m[this.id]=m[this.id]||{};if(0==arguments.length)return b("snap.data.get."+this.id,this,e,null),e;if(1==arguments.length){if(d.is(a,"object")){for(var f in a)a[A](f)&&this.data(f,a[f]);return this}return b("snap.data.get."+this.id,this,e[a],a),e[a]}return e[a]=c,b("snap.data.set."+this.id,this,c,a),this},a.removeData=function(a){return null==a?m[this.id]={}:m[this.id]&&delete m[this.id][a],this},a.outerSVG=a.toString=i(1),a.innerSVG=i()}(t.prototype),d.parse=function(a){var b=z.doc.createDocumentFragment(),c=!0,d=z.doc.createElement("div");if(a=B(a),a.match(/^\s*<\s*svg(?:\s|>)/)||(a=""+a+"",c=!1),d.innerHTML=a,a=d.getElementsByTagName("svg")[0])if(c)b=a;else for(;a.firstChild;)b.appendChild(a.firstChild);return d.innerHTML=J,new v(b)},v.prototype.select=t.prototype.select,v.prototype.selectAll=t.prototype.selectAll,d.fragment=function(){for(var a=Array.prototype.slice.call(arguments,0),b=z.doc.createDocumentFragment(),c=0,e=a.length;e>c;c++){var f=a[c];f.node&&f.node.nodeType&&b.appendChild(f.node),f.nodeType&&b.appendChild(f),"string"==typeof f&&b.appendChild(d.parse(f).node)}return new v(b)},d._.make=w,d._.wrap=y,x.prototype.el=function(a,b){var c=w(a,this.node);return b&&c.attr(b),c},b.on("snap.util.getattr",function(){var a=b.nt();a=a.substring(a.lastIndexOf(".")+1);var c=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});return fb[A](c)?this.node.ownerDocument.defaultView.getComputedStyle(this.node,null).getPropertyValue(c):e(this.node,a)});var fb={"alignment-baseline":0,"baseline-shift":0,clip:0,"clip-path":0,"clip-rule":0,color:0,"color-interpolation":0,"color-interpolation-filters":0,"color-profile":0,"color-rendering":0,cursor:0,direction:0,display:0,"dominant-baseline":0,"enable-background":0,fill:0,"fill-opacity":0,"fill-rule":0,filter:0,"flood-color":0,"flood-opacity":0,font:0,"font-family":0,"font-size":0,"font-size-adjust":0,"font-stretch":0,"font-style":0,"font-variant":0,"font-weight":0,"glyph-orientation-horizontal":0,"glyph-orientation-vertical":0,"image-rendering":0,kerning:0,"letter-spacing":0,"lighting-color":0,marker:0,"marker-end":0,"marker-mid":0,"marker-start":0,mask:0,opacity:0,overflow:0,"pointer-events":0,"shape-rendering":0,"stop-color":0,"stop-opacity":0,stroke:0,"stroke-dasharray":0,"stroke-dashoffset":0,"stroke-linecap":0,"stroke-linejoin":0,"stroke-miterlimit":0,"stroke-opacity":0,"stroke-width":0,"text-anchor":0,"text-decoration":0,"text-rendering":0,"unicode-bidi":0,visibility:0,"word-spacing":0,"writing-mode":0};b.on("snap.util.attr",function(a){var c=b.nt(),d={};c=c.substring(c.lastIndexOf(".")+1),d[c]=a;var f=c.replace(/-(\w)/gi,function(a,b){return b.toUpperCase()}),g=c.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});fb[A](g)?this.node.style[f]=null==a?J:a:e(this.node,d)}),function(){}(x.prototype),d.ajax=function(a,c,d,e){var g=new XMLHttpRequest,h=V();if(g){if(f(c,"function"))e=d,d=c,c=null;else if(f(c,"object")){var i=[];for(var j in c)c.hasOwnProperty(j)&&i.push(encodeURIComponent(j)+"="+encodeURIComponent(c[j]));c=i.join("&")}return g.open(c?"POST":"GET",a,!0),c&&(g.setRequestHeader("X-Requested-With","XMLHttpRequest"),g.setRequestHeader("Content-type","application/x-www-form-urlencoded")),d&&(b.once("snap.ajax."+h+".0",d),b.once("snap.ajax."+h+".200",d),b.once("snap.ajax."+h+".304",d)),g.onreadystatechange=function(){4==g.readyState&&b("snap.ajax."+h+"."+g.status,e,g)},4==g.readyState?g:(g.send(c),g)}},d.load=function(a,b,c){d.ajax(a,function(a){var e=d.parse(a.responseText);c?b.call(c,e):b(e)})};var gb=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,h=e.clientLeft||d.clientLeft||0,i=b.top+(g.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(g.win.pageXOffset||e.scrollLeft||d.scrollLeft)-h;return{y:i,x:j}};return d.getElementByPoint=function(a,b){var c=this,d=(c.canvas,z.doc.elementFromPoint(a,b));if(z.win.opera&&"svg"==d.tagName){var e=gb(d),f=d.createSVGRect();f.x=a-e.x,f.y=b-e.y,f.width=f.height=1;var g=d.getIntersectionList(f,null);g.length&&(d=g[g.length-1])}return d?y(d):null},d.plugin=function(a){a(d,t,x,z,v)},z.win.Snap=d,d}();return d.plugin(function(a){function b(a,b,d,e,f,g){return null==b&&"[object SVGMatrix]"==c.call(a)?(this.a=a.a,this.b=a.b,this.c=a.c,this.d=a.d,this.e=a.e,void(this.f=a.f)):void(null!=a?(this.a=+a,this.b=+b,this.c=+d,this.d=+e,this.e=+f,this.f=+g):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0))}var c=Object.prototype.toString,d=String,e=Math,f="";!function(c){function g(a){return a[0]*a[0]+a[1]*a[1]}function h(a){var b=e.sqrt(g(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}c.add=function(a,c,d,e,f,g){var h,i,j,k,l=[[],[],[]],m=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],n=[[a,d,f],[c,e,g],[0,0,1]];for(a&&a instanceof b&&(n=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),h=0;3>h;h++)for(i=0;3>i;i++){for(k=0,j=0;3>j;j++)k+=m[h][j]*n[j][i];l[h][i]=k}return this.a=l[0][0],this.b=l[1][0],this.c=l[0][1],this.d=l[1][1],this.e=l[0][2],this.f=l[1][2],this},c.invert=function(){var a=this,c=a.a*a.d-a.b*a.c;return new b(a.d/c,-a.b/c,-a.c/c,a.a/c,(a.c*a.f-a.d*a.e)/c,(a.b*a.e-a.a*a.f)/c)},c.clone=function(){return new b(this.a,this.b,this.c,this.d,this.e,this.f)},c.translate=function(a,b){return this.add(1,0,0,1,a,b)},c.scale=function(a,b,c,d){return null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d),this},c.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var f=+e.cos(b).toFixed(9),g=+e.sin(b).toFixed(9);return this.add(f,g,-g,f,c,d),this.add(1,0,0,1,-c,-d)},c.x=function(a,b){return a*this.a+b*this.c+this.e +},c.y=function(a,b){return a*this.b+b*this.d+this.f},c.get=function(a){return+this[d.fromCharCode(97+a)].toFixed(4)},c.toString=function(){return"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")"},c.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},c.determinant=function(){return this.a*this.d-this.b*this.c},c.split=function(){var b={};b.dx=this.e,b.dy=this.f;var c=[[this.a,this.c],[this.b,this.d]];b.scalex=e.sqrt(g(c[0])),h(c[0]),b.shear=c[0][0]*c[1][0]+c[0][1]*c[1][1],c[1]=[c[1][0]-c[0][0]*b.shear,c[1][1]-c[0][1]*b.shear],b.scaley=e.sqrt(g(c[1])),h(c[1]),b.shear/=b.scaley,this.determinant()<0&&(b.scalex=-b.scalex);var d=-c[0][1],f=c[1][1];return 0>f?(b.rotate=a.deg(e.acos(f)),0>d&&(b.rotate=360-b.rotate)):b.rotate=a.deg(e.asin(d)),b.isSimple=!(+b.shear.toFixed(9)||b.scalex.toFixed(9)!=b.scaley.toFixed(9)&&b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate,b},c.toTransformString=function(a){var b=a||this.split();return+b.shear.toFixed(9)?"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]:(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[+b.dx.toFixed(4),+b.dy.toFixed(4)]:f)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:f)+(b.rotate?"r"+[+b.rotate.toFixed(4),0,0]:f))}}(b.prototype),a.Matrix=b}),d.plugin(function(a,c,d,e,f){function g(d){return function(e){if(b.stop(),e instanceof f&&1==e.node.childNodes.length&&("radialGradient"==e.node.firstChild.tagName||"linearGradient"==e.node.firstChild.tagName||"pattern"==e.node.firstChild.tagName)&&(e=e.node.firstChild,m(this).appendChild(e),e=k(e)),e instanceof c)if("radialGradient"==e.type||"linearGradient"==e.type||"pattern"==e.type){e.node.id||o(e.node,{id:e.id});var g=p(e.node.id)}else g=e.attr(d);else if(g=a.color(e),g.error){var h=gradient(m(this),e);h?(h.node.id||o(h.node,{id:h.id}),g=p(h.node.id)):g=e}else g=q(g);var i={};i[d]=g,o(this.node,i),this.node.style[d]=s}}function h(a){for(var b=[],c=a.childNodes,d=0,e=c.length;e>d;d++){var f=c[d];3==f.nodeType&&b.push(f.nodeValue),"tspan"==f.tagName&&b.push(1==f.childNodes.length&&3==f.firstChild.nodeType?f.firstChild.nodeValue:h(f))}return b}function i(){return b.stop(),this.node.style.fontSize}var j=a._.make,k=a._.wrap,l=a.is,m=a._.getSomeDefs,n=/^url\(#?([^)]+)\)$/,o=a._.$,p=a.url,q=String,r=a._.separator,s="";b.on("snap.util.attr.mask",function(a){if(a instanceof c||a instanceof f){if(b.stop(),a instanceof f&&1==a.node.childNodes.length&&(a=a.node.firstChild,m(this).appendChild(a),a=k(a)),"mask"==a.type)var d=a;else d=j("mask",m(this)),d.node.appendChild(a.node),!d.node.id&&o(d.node,{id:d.id});o(this.node,{mask:p(d.id)})}}),function(a){b.on("snap.util.attr.clip",a),b.on("snap.util.attr.clip-path",a),b.on("snap.util.attr.clipPath",a)}(function(a){if(a instanceof c||a instanceof f){if(b.stop(),"clipPath"==a.type)var d=a;else d=j("clipPath",m(this)),d.node.appendChild(a.node),!d.node.id&&o(d.node,{id:d.id});o(this.node,{"clip-path":p(d.id)})}}),b.on("snap.util.attr.fill",g("fill")),b.on("snap.util.attr.stroke",g("stroke"));var t=/^([lr])(?:\(([^)]*)\))?(.*)$/i;b.on("snap.util.grad.parse",function(a){a=q(a);var b=a.match(t);if(!b)return null;var c=b[1],d=b[2],e=b[3];return d=d.split(/\s*,\s*/).map(function(a){return+a==a?+a:a}),1==d.length&&0==d[0]&&(d=[]),e=e.split("-"),e=e.map(function(a){a=a.split(":");var b={color:a[0]};return a[1]&&(b.offset=parseFloat(a[1])),b}),{type:c,params:d,stops:e}}),b.on("snap.util.attr.d",function(c){b.stop(),l(c,"array")&&l(c[0],"array")&&(c=a.path.toString.call(c)),c=q(c),c.match(/[ruo]/i)&&(c=a.path.toAbsolute(c)),o(this.node,{d:c})})(-1),b.on("snap.util.attr.#text",function(a){b.stop(),a=q(a);for(var c=e.doc.createTextNode(a);this.node.firstChild;)this.node.removeChild(this.node.firstChild);this.node.appendChild(c)})(-1),b.on("snap.util.attr.path",function(a){b.stop(),this.attr({d:a})})(-1),b.on("snap.util.attr.class",function(a){b.stop(),this.node.className.baseVal=a})(-1),b.on("snap.util.attr.viewBox",function(a){var c;c=l(a,"object")&&"x"in a?[a.x,a.y,a.width,a.height].join(" "):l(a,"array")?a.join(" "):a,o(this.node,{viewBox:c}),b.stop()})(-1),b.on("snap.util.attr.transform",function(a){this.transform(a),b.stop()})(-1),b.on("snap.util.attr.r",function(a){"rect"==this.type&&(b.stop(),o(this.node,{rx:a,ry:a}))})(-1),b.on("snap.util.attr.textpath",function(a){if(b.stop(),"text"==this.type){var d,e,f;if(!a&&this.textPath){for(e=this.textPath;e.node.firstChild;)this.node.appendChild(e.node.firstChild);return e.remove(),void delete this.textPath}if(l(a,"string")){var g=m(this),h=k(g.parentNode).path(a);g.appendChild(h.node),d=h.id,h.attr({id:d})}else a=k(a),a instanceof c&&(d=a.attr("id"),d||(d=a.id,a.attr({id:d})));if(d)if(e=this.textPath,f=this.node,e)e.attr({"xlink:href":"#"+d});else{for(e=o("textPath",{"xlink:href":"#"+d});f.firstChild;)e.appendChild(f.firstChild);f.appendChild(e),this.textPath=k(e)}}})(-1),b.on("snap.util.attr.text",function(a){if("text"==this.type){for(var c=this.node,d=function(a){var b=o("tspan");if(l(a,"array"))for(var c=0;c1&&(a=Array.prototype.slice.call(arguments,0));var b={};return g(a,"object")&&!g(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polyline",b)},f.polygon=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b={};return g(a,"object")&&!g(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polygon",b)},function(){function c(){return this.selectAll("stop")}function d(b,c){var d=k("stop"),e={offset:+c+"%"};return b=a.color(b),e["stop-color"]=b.hex,b.opacity<1&&(e["stop-opacity"]=b.opacity),k(d,e),this.node.appendChild(d),this}function e(){if("linearGradient"==this.type){var b=k(this.node,"x1")||0,c=k(this.node,"x2")||1,d=k(this.node,"y1")||0,e=k(this.node,"y2")||0;return a._.box(b,d,math.abs(c-b),math.abs(e-d))}var f=this.node.cx||.5,g=this.node.cy||.5,h=this.node.r||0;return a._.box(f-h,g-h,2*h,2*h)}function g(a){for(var b,c=0,d=a.length;d>c;c++)if(b=b||a[c])return b}function h(a,c){function d(a,b){for(var c=(b-m)/(a-n),d=n;a>d;d++)h[d].offset=+(+m+c*(d-n)).toFixed(2);n=a,m=b}var e,f=g(b("snap.util.grad.parse",null,c));if(!f)return null;f.params.unshift(a),e="l"==f.type.toLowerCase()?i.apply(0,f.params):j.apply(0,f.params),f.type!=f.type.toLowerCase()&&k(e.node,{gradientUnits:"userSpaceOnUse"});var h=f.stops,l=h.length,m=0,n=0;l--;for(var o=0;l>o;o++)"offset"in h[o]&&d(o,h[o].offset);for(h[l].offset=h[l].offset||100,d(l,h[l].offset),o=0;l>=o;o++){var p=h[o];e.addStop(p.color,p.offset)}return e}function i(b,f,g,h,i){var j=a._.make("linearGradient",b);return j.stops=c,j.addStop=d,j.getBBox=e,null!=f&&k(j.node,{x1:f,y1:g,x2:h,y2:i}),j}function j(b,f,g,h,i,j){var l=a._.make("radialGradient",b);return l.stops=c,l.addStop=d,l.getBBox=e,null!=f&&k(l.node,{cx:f,cy:g,r:h}),null!=i&&null!=j&&k(l.node,{fx:i,fy:j}),l}var k=a._.$;f.gradient=function(a){return h(this.defs,a)},f.gradientLinear=function(a,b,c,d){return i(this.defs,a,b,c,d)},f.gradientRadial=function(a,b,c,d,e){return j(this.defs,a,b,c,d,e)},f.toString=function(){var b,c=this.node.ownerDocument,d=c.createDocumentFragment(),e=c.createElement("div"),f=this.node.cloneNode(!0);return d.appendChild(e),e.appendChild(f),a._.$(f,{xmlns:"http://www.w3.org/2000/svg"}),b=e.innerHTML,d.removeChild(d.firstChild),b},f.clear=function(){for(var a,b=this.node.firstChild;b;)a=b.nextSibling,"defs"!=b.tagName?b.parentNode.removeChild(b):f.clear.call({node:b}),b=a}}()}),d.plugin(function(a,b){function c(a){var b=c.ps=c.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[K](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]}function d(a,b,c,d){return null==a&&(a=b=c=d=0),null==b&&(b=a.y,c=a.width,d=a.height,a=a.x),{x:a,y:b,width:c,w:c,height:d,h:d,x2:a+c,y2:b+d,cx:a+c/2,cy:b+d/2,r1:N.min(c,d)/2,r2:N.max(c,d)/2,r0:N.sqrt(c*c+d*d)/2,path:w(a,b,c,d),vb:[a,b,c,d].join(" ")}}function e(){return this.join(",").replace(L,"$1")}function f(a){var b=J(a);return b.toString=e,b}function g(a,b,c,d,e,f,g,h,j){return null==j?n(a,b,c,d,e,f,g,h):i(a,b,c,d,e,f,g,h,o(a,b,c,d,e,f,g,h,j))}function h(c,d){function e(a){return+(+a).toFixed(3)}return a._.cacher(function(a,f,h){a instanceof b&&(a=a.attr("d")),a=E(a);for(var j,k,l,m,n,o="",p={},q=0,r=0,s=a.length;s>r;r++){if(l=a[r],"M"==l[0])j=+l[1],k=+l[2];else{if(m=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6]),q+m>f){if(d&&!p.start){if(n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q),o+=["C"+e(n.start.x),e(n.start.y),e(n.m.x),e(n.m.y),e(n.x),e(n.y)],h)return o;p.start=o,o=["M"+e(n.x),e(n.y)+"C"+e(n.n.x),e(n.n.y),e(n.end.x),e(n.end.y),e(l[5]),e(l[6])].join(),q+=m,j=+l[5],k=+l[6];continue}if(!c&&!d)return n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q)}q+=m,j=+l[5],k=+l[6]}o+=l.shift()+l}return p.end=o,n=c?q:d?p:i(j,k,l[0],l[1],l[2],l[3],l[4],l[5],1)},null,a._.clone)}function i(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/O;return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}}function j(b,c,e,f,g,h,i,j){a.is(b,"array")||(b=[b,c,e,f,g,h,i,j]);var k=D.apply(null,b);return d(k.min.x,k.min.y,k.max.x-k.min.x,k.max.y-k.min.y)}function k(a,b,c){return b>=a.x&&b<=a.x+a.width&&c>=a.y&&c<=a.y+a.height}function l(a,b){return a=d(a),b=d(b),k(b,a.x,a.y)||k(b,a.x2,a.y)||k(b,a.x,a.y2)||k(b,a.x2,a.y2)||k(a,b.x,b.y)||k(a,b.x2,b.y)||k(a,b.x,b.y2)||k(a,b.x2,b.y2)||(a.xb.x||b.xa.x)&&(a.yb.y||b.ya.y)}function m(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function n(a,b,c,d,e,f,g,h,i){null==i&&(i=1),i=i>1?1:0>i?0:i;for(var j=i/2,k=12,l=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;k>p;p++){var q=j*l[p]+j,r=m(q,a,c,e,g),s=m(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return j*o}function o(a,b,c,d,e,f,g,h,i){if(!(0>i||n(a,b,c,d,e,f,g,h)o;)l/=2,m+=(i>j?1:-1)*l,j=n(a,b,c,d,e,f,g,h,m);return m}}function p(a,b,c,d,e,f,g,h){if(!(Q(a,c)Q(e,g)||Q(b,d)Q(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+Q(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+Q(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+Q(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+Q(f,h).toFixed(2)))return{x:l,y:m}}}}function q(a,b,c){var d=j(a),e=j(b);if(!l(d,e))return c?0:[];for(var f=n.apply(0,a),g=n.apply(0,b),h=~~(f/5),k=~~(g/5),m=[],o=[],q={},r=c?0:[],s=0;h+1>s;s++){var t=i.apply(0,a.concat(s/h));m.push({x:t.x,y:t.y,t:s/h})}for(s=0;k+1>s;s++)t=i.apply(0,b.concat(s/k)),o.push({x:t.x,y:t.y,t:s/k});for(s=0;h>s;s++)for(var u=0;k>u;u++){var v=m[s],w=m[s+1],x=o[u],y=o[u+1],z=S(w.x-v.x)<.001?"y":"x",A=S(y.x-x.x)<.001?"y":"x",B=p(v.x,v.y,w.x,w.y,x.x,x.y,y.x,y.y);if(B){if(q[B.x.toFixed(4)]==B.y.toFixed(4))continue;q[B.x.toFixed(4)]=B.y.toFixed(4);var C=v.t+S((B[z]-v[z])/(w[z]-v[z]))*(w.t-v.t),D=x.t+S((B[A]-x[A])/(y[A]-x[A]))*(y.t-x.t);C>=0&&1>=C&&D>=0&&1>=D&&(c?r++:r.push({x:B.x,y:B.y,t1:C,t2:D}))}}return r}function r(a,b){return t(a,b)}function s(a,b){return t(a,b,1)}function t(a,b,c){a=E(a),b=E(b);for(var d,e,f,g,h,i,j,k,l,m,n=c?0:[],o=0,p=a.length;p>o;o++){var r=a[o];if("M"==r[0])d=h=r[1],e=i=r[2];else{"C"==r[0]?(l=[d,e].concat(r.slice(1)),d=l[6],e=l[7]):(l=[d,e,d,e,h,i,h,i],d=h,e=i);for(var s=0,t=b.length;t>s;s++){var u=b[s];if("M"==u[0])f=j=u[1],g=k=u[2];else{"C"==u[0]?(m=[f,g].concat(u.slice(1)),f=m[6],g=m[7]):(m=[f,g,f,g,j,k,j,k],f=j,g=k);var v=q(l,m,c);if(c)n+=v;else{for(var w=0,x=v.length;x>w;w++)v[w].segment1=o,v[w].segment2=s,v[w].bez1=l,v[w].bez2=m;n=n.concat(v)}}}}}return n}function u(a,b,c){var d=v(a);return k(d,b,c)&&t(a,[["M",b,c],["H",d.x2+10]],1)%2==1}function v(a){var b=c(a);if(b.bbox)return J(b.bbox);if(!a)return d();a=E(a);for(var e,f=0,g=0,h=[],i=[],j=0,k=a.length;k>j;j++)if(e=a[j],"M"==e[0])f=e[1],g=e[2],h.push(f),i.push(g);else{var l=D(f,g,e[1],e[2],e[3],e[4],e[5],e[6]);h=h.concat(l.min.x,l.max.x),i=i.concat(l.min.y,l.max.y),f=e[5],g=e[6]}var m=P.apply(0,h),n=P.apply(0,i),o=Q.apply(0,h),p=Q.apply(0,i),q=d(m,n,o-m,p-n);return b.bbox=J(q),q}function w(a,b,c,d,f){if(f)return[["M",+a+ +f,b],["l",c-2*f,0],["a",f,f,0,0,1,f,f],["l",0,d-2*f],["a",f,f,0,0,1,-f,f],["l",2*f-c,0],["a",f,f,0,0,1,-f,-f],["l",0,2*f-d],["a",f,f,0,0,1,f,-f],["z"]];var g=[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]];return g.toString=e,g}function x(a,b,c,d,f){if(null==f&&null==d&&(d=c),a=+a,b=+b,c=+c,d=+d,null!=f)var g=Math.PI/180,h=a+c*Math.cos(-d*g),i=a+c*Math.cos(-f*g),j=b+c*Math.sin(-d*g),k=b+c*Math.sin(-f*g),l=[["M",h,j],["A",c,c,0,+(f-d>180),0,i,k]];else l=[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]];return l.toString=e,l}function y(b){var d=c(b),g=String.prototype.toLowerCase;if(d.rel)return f(d.rel);a.is(b,"array")&&a.is(b&&b[0],"array")||(b=a.parsePathString(b));var h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=b[0][1],j=b[0][2],k=i,l=j,m++,h.push(["M",i,j]));for(var n=m,o=b.length;o>n;n++){var p=h[n]=[],q=b[n];if(q[0]!=g.call(q[0]))switch(p[0]=g.call(q[0]),p[0]){case"a":p[1]=q[1],p[2]=q[2],p[3]=q[3],p[4]=q[4],p[5]=q[5],p[6]=+(q[6]-i).toFixed(3),p[7]=+(q[7]-j).toFixed(3);break;case"v":p[1]=+(q[1]-j).toFixed(3);break;case"m":k=q[1],l=q[2];default:for(var r=1,s=q.length;s>r;r++)p[r]=+(q[r]-(r%2?i:j)).toFixed(3)}else{p=h[n]=[],"m"==q[0]&&(k=q[1]+i,l=q[2]+j);for(var t=0,u=q.length;u>t;t++)h[n][t]=q[t]}var v=h[n].length;switch(h[n][0]){case"z":i=k,j=l;break;case"h":i+=+h[n][v-1];break;case"v":j+=+h[n][v-1];break;default:i+=+h[n][v-2],j+=+h[n][v-1]}}return h.toString=e,d.rel=f(h),h}function z(b){var d=c(b);if(d.abs)return f(d.abs);if(I(b,"array")&&I(b&&b[0],"array")||(b=a.parsePathString(b)),!b||!b.length)return[["M",0,0]];var g,h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=+b[0][1],j=+b[0][2],k=i,l=j,m++,h[0]=["M",i,j]);for(var n,o,p=3==b.length&&"M"==b[0][0]&&"R"==b[1][0].toUpperCase()&&"Z"==b[2][0].toUpperCase(),q=m,r=b.length;r>q;q++){if(h.push(n=[]),o=b[q],g=o[0],g!=g.toUpperCase())switch(n[0]=g.toUpperCase(),n[0]){case"A":n[1]=o[1],n[2]=o[2],n[3]=o[3],n[4]=o[4],n[5]=o[5],n[6]=+o[6]+i,n[7]=+o[7]+j;break;case"V":n[1]=+o[1]+j;break;case"H":n[1]=+o[1]+i;break;case"R":for(var s=[i,j].concat(o.slice(1)),t=2,u=s.length;u>t;t++)s[t]=+s[t]+i,s[++t]=+s[t]+j;h.pop(),h=h.concat(G(s,p));break;case"O":h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);break;case"U":h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));break;case"M":k=+o[1]+i,l=+o[2]+j;default:for(t=1,u=o.length;u>t;t++)n[t]=+o[t]+(t%2?i:j)}else if("R"==g)s=[i,j].concat(o.slice(1)),h.pop(),h=h.concat(G(s,p)),n=["R"].concat(o.slice(-2));else if("O"==g)h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);else if("U"==g)h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));else for(var v=0,w=o.length;w>v;v++)n[v]=o[v];if(g=g.toUpperCase(),"O"!=g)switch(n[0]){case"Z":i=+k,j=+l;break;case"H":i=n[1];break;case"V":j=n[1];break;case"M":k=n[n.length-2],l=n[n.length-1];default:i=n[n.length-2],j=n[n.length-1]}}return h.toString=e,d.abs=f(h),h}function A(a,b,c,d){return[a,b,c,d,c,d]}function B(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]}function C(b,c,d,e,f,g,h,i,j,k){var l,m=120*O/180,n=O/180*(+f||0),o=[],p=a._.cacher(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(b,c,-n),b=l.x,c=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(O/180*f),N.sin(O/180*f),(b-i)/2),r=(c-j)/2,s=q*q/(d*d)+r*r/(e*e);s>1&&(s=N.sqrt(s),d=s*d,e=s*e);var t=d*d,u=e*e,v=(g==h?-1:1)*N.sqrt(S((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*d*r/e+(b+i)/2,x=v*-e*q/d+(c+j)/2,y=N.asin(((c-x)/e).toFixed(9)),z=N.asin(((j-x)/e).toFixed(9));y=w>b?O-y:y,z=w>i?O-z:z,0>y&&(y=2*O+y),0>z&&(z=2*O+z),h&&y>z&&(y-=2*O),!h&&z>y&&(z-=2*O)}var A=z-y;if(S(A)>m){var B=z,D=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+d*N.cos(z),j=x+e*N.sin(z),o=C(i,j,d,e,f,0,h,D,E,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),J=N.tan(A/4),K=4/3*d*J,L=4/3*e*J,M=[b,c],P=[b+K*G,c-L*F],Q=[i+K*I,j-L*H],R=[i,j];if(P[0]=2*M[0]-P[0],P[1]=2*M[1]-P[1],k)return[P,Q,R].concat(o);o=[P,Q,R].concat(o).join().split(",");for(var T=[],U=0,V=o.length;V>U;U++)T[U]=U%2?p(o[U-1],o[U],n).y:p(o[U],o[U+1],n).x;return T}function D(a,b,c,d,e,f,g,h){for(var i,j,k,l,m,n,o,p,q=[],r=[[],[]],s=0;2>s;++s)if(0==s?(j=6*a-12*c+6*e,i=-3*a+9*c-9*e+3*g,k=3*c-3*a):(j=6*b-12*d+6*f,i=-3*b+9*d-9*f+3*h,k=3*d-3*b),S(i)<1e-12){if(S(j)<1e-12)continue;l=-k/j,l>0&&1>l&&q.push(l)}else o=j*j-4*k*i,p=N.sqrt(o),0>o||(m=(-j+p)/(2*i),m>0&&1>m&&q.push(m),n=(-j-p)/(2*i),n>0&&1>n&&q.push(n));for(var t,u=q.length,v=u;u--;)l=q[u],t=1-l,r[0][u]=t*t*t*a+3*t*t*l*c+3*t*l*l*e+l*l*l*g,r[1][u]=t*t*t*b+3*t*t*l*d+3*t*l*l*f+l*l*l*h;return r[0][v]=a,r[1][v]=b,r[0][v+1]=g,r[1][v+1]=h,r[0].length=r[1].length=v+2,{min:{x:P.apply(0,r[0]),y:P.apply(0,r[1])},max:{x:Q.apply(0,r[0]),y:Q.apply(0,r[1])}}}function E(a,b){var d=!b&&c(a);if(!b&&d.curve)return f(d.curve);for(var e=z(a),g=b&&z(b),h={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},i={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},j=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"].concat(C.apply(0,[b.x,b.y].concat(a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e].concat(a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"].concat(B(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"].concat(B(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"].concat(A(b.x,b.y,a[1],a[2]));break;case"H":a=["C"].concat(A(b.x,b.y,a[1],b.y));break;case"V":a=["C"].concat(A(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"].concat(A(b.x,b.y,b.X,b.Y))}return a}),k=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)m[b]="A",g&&(n[b]="A"),a.splice(b++,0,["C"].concat(c.splice(0,6)));a.splice(b,1),r=Q(e.length,g&&g.length||0)}},l=function(a,b,c,d,f){a&&b&&"M"==a[f][0]&&"M"!=b[f][0]&&(b.splice(f,0,["M",d.x,d.y]),c.bx=0,c.by=0,c.x=a[f][1],c.y=a[f][2],r=Q(e.length,g&&g.length||0))},m=[],n=[],o="",p="",q=0,r=Q(e.length,g&&g.length||0);r>q;q++){e[q]&&(o=e[q][0]),"C"!=o&&(m[q]=o,q&&(p=m[q-1])),e[q]=j(e[q],h,p),"A"!=m[q]&&"C"==o&&(m[q]="C"),k(e,q),g&&(g[q]&&(o=g[q][0]),"C"!=o&&(n[q]=o,q&&(p=n[q-1])),g[q]=j(g[q],i,p),"A"!=n[q]&&"C"==o&&(n[q]="C"),k(g,q)),l(e,g,h,i,q),l(g,e,i,h,q);var s=e[q],t=g&&g[q],u=s.length,v=g&&t.length;h.x=s[u-2],h.y=s[u-1],h.bx=M(s[u-4])||h.x,h.by=M(s[u-3])||h.y,i.bx=g&&(M(t[v-4])||i.x),i.by=g&&(M(t[v-3])||i.y),i.x=g&&t[v-2],i.y=g&&t[v-1]}return g||(d.curve=f(e)),g?[e,g]:e}function F(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=E(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a}function G(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}var H=b.prototype,I=a.is,J=a._.clone,K="hasOwnProperty",L=/,?([a-z]),?/gi,M=parseFloat,N=Math,O=N.PI,P=N.min,Q=N.max,R=N.pow,S=N.abs,T=h(1),U=h(),V=h(0,1),W=a._unit2px,X={path:function(a){return a.attr("path")},circle:function(a){var b=W(a);return x(b.cx,b.cy,b.r)},ellipse:function(a){var b=W(a);return x(b.cx||0,b.cy||0,b.rx,b.ry)},rect:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height,b.rx,b.ry)},image:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height)},text:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)},g:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)},symbol:function(a){var b=a.getBBox();return w(b.x,b.y,b.width,b.height)},line:function(a){return"M"+[a.attr("x1")||0,a.attr("y1")||0,a.attr("x2"),a.attr("y2")]},polyline:function(a){return"M"+a.attr("points")},polygon:function(a){return"M"+a.attr("points")+"z"},svg:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)},deflt:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)}};a.path=c,a.path.getTotalLength=T,a.path.getPointAtLength=U,a.path.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return V(a,b).end;var d=V(a,c,1);return b?V(d,b).end:d},H.getTotalLength=function(){return this.node.getTotalLength?this.node.getTotalLength():void 0},H.getPointAtLength=function(a){return U(this.attr("d"),a)},H.getSubpath=function(b,c){return a.path.getSubpath(this.attr("d"),b,c)},a._.box=d,a.path.findDotsAtSegment=i,a.path.bezierBBox=j,a.path.isPointInsideBBox=k,a.path.isBBoxIntersect=l,a.path.intersection=r,a.path.intersectionNumber=s,a.path.isPointInside=u,a.path.getBBox=v,a.path.get=X,a.path.toRelative=y,a.path.toAbsolute=z,a.path.toCubic=E,a.path.map=F,a.path.toString=e,a.path.clone=f}),d.plugin(function(a){var d=Math.max,e=Math.min,f=function(a){if(this.items=[],this.length=0,this.type="set",a)for(var b=0,c=a.length;c>b;b++)a[b]&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},g=f.prototype;g.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],a&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},g.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},g.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this},g.animate=function(d,e,f,g){"function"!=typeof f||f.length||(g=f,f=c.linear),d instanceof a._.Animation&&(g=d.callback,f=d.easing,e=f.dur,d=d.attr);var h,i=function(){h?this.b=h:h=this.b},j=0,k=g&&function(){j++==this.length&&g.call(this)};return this.forEach(function(a){b.once("snap.animcreated."+a.id,i),a.animate(d,e,f,k)})},g.animateEach=function(){var a,c=0,d=this,e=function(){a?this.b=a:a=this.b},f=arguments,g=function(a){var f=d[c++];return f&&(f.animate.apply(f,arguments.length>1?arguments:a),b.once("snap.animcreated."+f.id,e)),d[c]?g:d};return g(f)},g.remove=function(){for(;this.length;)this.pop().remove();return this},g.attr=function(a){for(var b=0,c=this.items.length;c>b;b++)this.items[b].attr(a);return this},g.clear=function(){for(;this.length;)this.pop()},g.splice=function(a,b){a=0>a?d(this.length+a,0):a,b=d(0,e(this.length-a,b));var c,g=[],h=[],i=[];for(c=2;cc;c++)h.push(this[a+c]);for(;cc?i[c]:g[c-j];for(c=this.items.length=this.length-=b-j;this[c];)delete this[c++];return new f(h)},g.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0;return!1},g.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},g.getBBox=function(){for(var a=[],b=[],c=[],f=[],g=this.items.length;g--;)if(!this.items[g].removed){var h=this.items[g].getBBox();a.push(h.x),b.push(h.y),c.push(h.x+h.width),f.push(h.y+h.height)}return a=e.apply(0,a),b=e.apply(0,b),c=d.apply(0,c),f=d.apply(0,f),{x:a,y:b,x2:c,y2:f,width:c-a,height:f-b,cx:a+(c-a)/2,cy:b+(f-b)/2}},g.clone=function(a){a=new f;for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},g.toString=function(){return"Snap‘s set"},g.type="set",a.set=function(){var a=new f;return arguments.length&&a.push.apply(a,Array.prototype.slice.call(arguments,0)),a}}),d.plugin(function(a,b){function c(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}}function d(b,d,e){d=l(d).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],d=a.parseTransformString(d)||[];for(var f,g,j,k,m=Math.max(b.length,d.length),n=[],o=[],p=0;m>p;p++){if(j=b[p]||c(d[p]),k=d[p]||c(j),j[0]!=k[0]||"r"==j[0].toLowerCase()&&(j[2]!=k[2]||j[3]!=k[3])||"s"==j[0].toLowerCase()&&(j[3]!=k[3]||j[4]!=k[4])){b=a._.transform2matrix(b,e()),d=a._.transform2matrix(d,e()),n=[["m",b.a,b.b,b.c,b.d,b.e,b.f]],o=[["m",d.a,d.b,d.c,d.d,d.e,d.f]];break}for(n[p]=[],o[p]=[],f=0,g=Math.max(j.length,k.length);g>f;f++)f in j&&(n[p][f]=j[f]),f in k&&(o[p][f]=k[f])}return{from:i(n),to:i(o),f:h(n)}}function e(a){return a}function f(a){return function(b){return+b.toFixed(3)+a}}function g(b){return a.rgb(b[0],b[1],b[2])}function h(a){var b,c,d,e,f,g,h=0,i=[];for(b=0,c=a.length;c>b;b++){for(f="[",g=['"'+a[b][0]+'"'],d=1,e=a[b].length;e>d;d++)g[d]="val["+h++ +"]";f+=g+"]",i[b]=f}return Function("val","return Snap.path.toString.call(["+i+"])")}function i(a){for(var b=[],c=0,d=a.length;d>c;c++)for(var e=1,f=a[c].length;f>e;e++)b.push(a[c][e]);return b}var j={},k=/[a-z]+$/i,l=String;j.stroke=j.fill="colour",b.prototype.equal=function(b,c){var m,n,o=l(this.attr(b)||""),p=this;if(o==+o&&c==+c)return{from:+o,to:+c,f:e};if("colour"==j[b])return m=a.color(o),n=a.color(c),{from:[m.r,m.g,m.b,m.opacity],to:[n.r,n.g,n.b,n.opacity],f:g};if("transform"==b||"gradientTransform"==b||"patternTransform"==b)return c instanceof a.Matrix&&(c=c.toTransformString()),a._.rgTransform.test(c)||(c=a._.svgTransform2string(c)),d(o,c,function(){return p.getBBox(1)});if("d"==b||"path"==b)return m=a.path.toCubic(o,c),{from:i(m[0]),to:i(m[1]),f:h(m[0])};if("points"==b)return m=l(o).split(","),n=l(c).split(","),{from:m,to:n,f:function(a){return a}};var q=o.match(k),r=l(c).match(k);return q&&q==r?{from:parseFloat(o),to:parseFloat(c),f:f(q)}:{from:this.asPX(b),to:this.asPX(b,c),f:e}}}),d.plugin(function(a,c,d,e){for(var f=c.prototype,g="hasOwnProperty",h=("createTouch"in e.doc),i=["click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup","touchstart","touchmove","touchend","touchcancel"],j={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},k=function(a){var b="y"==a?"scrollTop":"scrollLeft";return e.doc.documentElement[b]||e.doc.body[b]},l=function(){this.returnValue=!1},m=function(){return this.originalEvent.preventDefault()},n=function(){this.cancelBubble=!0},o=function(){return this.originalEvent.stopPropagation()},p=function(){return e.doc.addEventListener?function(a,b,c,d){var e=h&&j[b]?j[b]:b,f=function(e){var f=k("y"),i=k("x");if(h&&j[g](b))for(var l=0,n=e.targetTouches&&e.targetTouches.length;n>l;l++)if(e.targetTouches[l].target==a||a.contains(e.targetTouches[l].target)){var p=e;e=e.targetTouches[l],e.originalEvent=p,e.preventDefault=m,e.stopPropagation=o; +break}var q=e.clientX+i,r=e.clientY+f;return c.call(d,e,q,r)};return b!==e&&a.addEventListener(b,f,!1),a.addEventListener(e,f,!1),function(){return b!==e&&a.removeEventListener(b,f,!1),a.removeEventListener(e,f,!1),!0}}:e.doc.attachEvent?function(a,b,c,d){var f=function(a){a=a||e.win.event;var b=k("y"),f=k("x"),g=a.clientX+f,h=a.clientY+b;return a.preventDefault=a.preventDefault||l,a.stopPropagation=a.stopPropagation||n,c.call(d,a,g,h)};a.attachEvent("on"+b,f);var g=function(){return a.detachEvent("on"+b,f),!0};return g}:void 0}(),q=[],r=function(c){for(var d,e=c.clientX,f=c.clientY,g=k("y"),i=k("x"),j=q.length;j--;){if(d=q[j],h){for(var l,m=c.touches&&c.touches.length;m--;)if(l=c.touches[m],l.identifier==d.el._drag.id||d.el.node.contains(l.target)){e=l.clientX,f=l.clientY,(c.originalEvent?c.originalEvent:c).preventDefault();break}}else c.preventDefault();{var n=d.el.node;a._.glob,n.nextSibling,n.parentNode,n.style.display}e+=i,f+=g,b("snap.drag.move."+d.el.id,d.move_scope||d.el,e-d.el._drag.x,f-d.el._drag.y,e,f,c)}},s=function(c){a.unmousemove(r).unmouseup(s);for(var d,e=q.length;e--;)d=q[e],d.el._drag={},b("snap.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c);q=[]},t=i.length;t--;)!function(b){a[b]=f[b]=function(c,d){return a.is(c,"function")&&(this.events=this.events||[],this.events.push({name:b,f:c,unbind:p(this.shape||this.node||e.doc,b,c,d||this)})),this},a["un"+b]=f["un"+b]=function(a){for(var c=this.events||[],d=c.length;d--;)if(c[d].name==b&&(c[d].f==a||!a))return c[d].unbind(),c.splice(d,1),!c.length&&delete this.events,this;return this}}(i[t]);f.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},f.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var u=[];f.drag=function(c,d,e,f,g,h){function i(i,j,k){(i.originalEvent||i).preventDefault(),this._drag.x=j,this._drag.y=k,this._drag.id=i.identifier,!q.length&&a.mousemove(r).mouseup(s),q.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("snap.drag.start."+this.id,d),c&&b.on("snap.drag.move."+this.id,c),e&&b.on("snap.drag.end."+this.id,e),b("snap.drag.start."+this.id,g||f||this,j,k,i)}if(!arguments.length){var j;return this.drag(function(a,b){this.attr({transform:j+(j?"T":"t")+[a,b]})},function(){j=this.transform().local})}return this._drag={},u.push({el:this,start:i}),this.mousedown(i),this},f.undrag=function(){for(var c=u.length;c--;)u[c].el==this&&(this.unmousedown(u[c].start),u.splice(c,1),b.unbind("snap.drag.*."+this.id));return!u.length&&a.unmousemove(r).unmouseup(s),this}}),d.plugin(function(a,c,d){var e=(c.prototype,d.prototype),f=/^\s*url\((.+)\)/,g=String,h=a._.$;a.filter={},e.filter=function(b){var d=this;"svg"!=d.type&&(d=d.paper);var e=a.parse(g(b)),f=a._.id(),i=(d.node.offsetWidth,d.node.offsetHeight,h("filter"));return h(i,{id:f,filterUnits:"userSpaceOnUse"}),i.appendChild(e.node),d.defs.appendChild(i),new c(i)},b.on("snap.util.getattr.filter",function(){b.stop();var c=h(this.node,"filter");if(c){var d=g(c).match(f);return d&&a.select(d[1])}}),b.on("snap.util.attr.filter",function(d){if(d instanceof c&&"filter"==d.type){b.stop();var e=d.node.id;e||(h(d.node,{id:d.id}),e=d.id),h(this.node,{filter:a.url(e)})}d&&"none"!=d||(b.stop(),this.node.removeAttribute("filter"))}),a.filter.blur=function(b,c){null==b&&(b=2);var d=null==c?b:[b,c];return a.format('',{def:d})},a.filter.blur.toString=function(){return this()},a.filter.shadow=function(b,c,d,e,f){return"string"==typeof d&&(e=d,f=e,d=4),"string"!=typeof e&&(f=e,e="#000"),e=e||"#000",null==d&&(d=4),null==f&&(f=1),null==b&&(b=0,c=2),null==c&&(c=b),e=a.color(e),a.format('',{color:e,dx:b,dy:c,blur:d,opacity:f})},a.filter.shadow.toString=function(){return this()},a.filter.grayscale=function(b){return null==b&&(b=1),a.format('',{a:.2126+.7874*(1-b),b:.7152-.7152*(1-b),c:.0722-.0722*(1-b),d:.2126-.2126*(1-b),e:.7152+.2848*(1-b),f:.0722-.0722*(1-b),g:.2126-.2126*(1-b),h:.0722+.9278*(1-b)})},a.filter.grayscale.toString=function(){return this()},a.filter.sepia=function(b){return null==b&&(b=1),a.format('',{a:.393+.607*(1-b),b:.769-.769*(1-b),c:.189-.189*(1-b),d:.349-.349*(1-b),e:.686+.314*(1-b),f:.168-.168*(1-b),g:.272-.272*(1-b),h:.534-.534*(1-b),i:.131+.869*(1-b)})},a.filter.sepia.toString=function(){return this()},a.filter.saturate=function(b){return null==b&&(b=1),a.format('',{amount:1-b})},a.filter.saturate.toString=function(){return this()},a.filter.hueRotate=function(b){return b=b||0,a.format('',{angle:b})},a.filter.hueRotate.toString=function(){return this()},a.filter.invert=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:1-b})},a.filter.invert.toString=function(){return this()},a.filter.brightness=function(b){return null==b&&(b=1),a.format('',{amount:b})},a.filter.brightness.toString=function(){return this()},a.filter.contrast=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:.5-b/2})},a.filter.contrast.toString=function(){return this()}}),d}); \ No newline at end of file diff --git a/dist/snap.svg.js b/dist/snap.svg.js index 12b7f44..1d09cdb 100644 --- a/dist/snap.svg.js +++ b/dist/snap.svg.js @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// build: 2014-05-05 +// build: 2014-05-07 // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -836,7 +836,7 @@ var has = "hasOwnProperty", bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, reURLValue = /^url\(#?([^)]+)\)$/, spaces = "\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029", - separator = new RegExp("[," + spaces + "]+"), + separator = Snap._.separator = new RegExp("[," + spaces + "]+"), whitespace = new RegExp("[" + spaces + "]", "g"), commaSpaces = new RegExp("[" + spaces + "]*,[" + spaces + "]*"), hsrg = {hs: 1, rg: 1}, @@ -967,24 +967,6 @@ Snap.format = (function () { }); }; })(); -var preload = (function () { - function onerror() { - this.parentNode.removeChild(this); - } - return function (src, f) { - var img = glob.doc.createElement("img"), - body = glob.doc.body; - img.style.cssText = "position:absolute;left:-9999em;top:-9999em"; - img.onload = function () { - f.call(img); - img.onload = img.onerror = null; - body.removeChild(img); - }; - img.onerror = onerror; - body.appendChild(img); - img.src = src; - }; -}()); function clone(obj) { if (typeof obj == "function" || Object(obj) !== obj) { return obj; @@ -1062,7 +1044,6 @@ Snap.rad = rad; = (number) angle in degrees \*/ Snap.deg = deg; -// SIERRA for which point is the angle calculated? /*\ * Snap.angle [ method ] @@ -1117,288 +1098,6 @@ Snap.snapTo = function (values, value, tolerance) { } return value; }; - -// MATRIX -function Matrix(a, b, c, d, e, f) { - if (b == null && objectToString.call(a) == "[object SVGMatrix]") { - this.a = a.a; - this.b = a.b; - this.c = a.c; - this.d = a.d; - this.e = a.e; - this.f = a.f; - return; - } - if (a != null) { - this.a = +a; - this.b = +b; - this.c = +c; - this.d = +d; - this.e = +e; - this.f = +f; - } else { - this.a = 1; - this.b = 0; - this.c = 0; - this.d = 1; - this.e = 0; - this.f = 0; - } -} -(function (matrixproto) { - /*\ - * Matrix.add - [ method ] - ** - * Adds the given matrix to existing one - - a (number) - - b (number) - - c (number) - - d (number) - - e (number) - - f (number) - * or - - matrix (object) @Matrix - \*/ - matrixproto.add = function (a, b, c, d, e, f) { - var out = [[], [], []], - m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], - matrix = [[a, c, e], [b, d, f], [0, 0, 1]], - x, y, z, res; - - if (a && a instanceof Matrix) { - matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]; - } - - for (x = 0; x < 3; x++) { - for (y = 0; y < 3; y++) { - res = 0; - for (z = 0; z < 3; z++) { - res += m[x][z] * matrix[z][y]; - } - out[x][y] = res; - } - } - this.a = out[0][0]; - this.b = out[1][0]; - this.c = out[0][1]; - this.d = out[1][1]; - this.e = out[0][2]; - this.f = out[1][2]; - return this; - }; - /*\ - * Matrix.invert - [ method ] - ** - * Returns an inverted version of the matrix - = (object) @Matrix - \*/ - matrixproto.invert = function () { - var me = this, - x = me.a * me.d - me.b * me.c; - return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x); - }; - /*\ - * Matrix.clone - [ method ] - ** - * Returns a copy of the matrix - = (object) @Matrix - \*/ - matrixproto.clone = function () { - return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f); - }; - /*\ - * Matrix.translate - [ method ] - ** - * Translate the matrix - - x (number) horizontal offset distance - - y (number) vertical offset distance - \*/ - matrixproto.translate = function (x, y) { - return this.add(1, 0, 0, 1, x, y); - }; - /*\ - * Matrix.scale - [ method ] - ** - * Scales the matrix - - x (number) amount to be scaled, with `1` resulting in no change - - y (number) #optional amount to scale along the vertical axis. (Otherwise `x` applies to both axes.) - - cx (number) #optional horizontal origin point from which to scale - - cy (number) #optional vertical origin point from which to scale - * Default cx, cy is the middle point of the element. - \*/ - matrixproto.scale = function (x, y, cx, cy) { - y == null && (y = x); - (cx || cy) && this.add(1, 0, 0, 1, cx, cy); - this.add(x, 0, 0, y, 0, 0); - (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy); - return this; - }; - /*\ - * Matrix.rotate - [ method ] - ** - * Rotates the matrix - - a (number) angle of rotation, in degrees - - x (number) horizontal origin point from which to rotate - - y (number) vertical origin point from which to rotate - \*/ - matrixproto.rotate = function (a, x, y) { - a = rad(a); - x = x || 0; - y = y || 0; - var cos = +math.cos(a).toFixed(9), - sin = +math.sin(a).toFixed(9); - this.add(cos, sin, -sin, cos, x, y); - return this.add(1, 0, 0, 1, -x, -y); - }; - /*\ - * Matrix.x - [ method ] - ** - * Returns x coordinate for given point after transformation described by the matrix. See also @Matrix.y - - x (number) - - y (number) - = (number) x - \*/ - matrixproto.x = function (x, y) { - return x * this.a + y * this.c + this.e; - }; - /*\ - * Matrix.y - [ method ] - ** - * Returns y coordinate for given point after transformation described by the matrix. See also @Matrix.x - - x (number) - - y (number) - = (number) y - \*/ - matrixproto.y = function (x, y) { - return x * this.b + y * this.d + this.f; - }; - matrixproto.get = function (i) { - return +this[Str.fromCharCode(97 + i)].toFixed(4); - }; - matrixproto.toString = function () { - return "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")"; - }; - matrixproto.offset = function () { - return [this.e.toFixed(4), this.f.toFixed(4)]; - }; - function norm(a) { - return a[0] * a[0] + a[1] * a[1]; - } - function normalize(a) { - var mag = math.sqrt(norm(a)); - a[0] && (a[0] /= mag); - a[1] && (a[1] /= mag); - } - /*\ - * Matrix.determinant - [ method ] - ** - * Finds determinant of the given matrix. - = (number) determinant - \*/ - matrixproto.determinant = function () { - return this.a * this.d - this.b * this.c; - }; - /*\ - * Matrix.split - [ method ] - ** - * Splits matrix into primitive transformations - = (object) in format: - o dx (number) translation by x - o dy (number) translation by y - o scalex (number) scale by x - o scaley (number) scale by y - o shear (number) shear - o rotate (number) rotation in deg - o isSimple (boolean) could it be represented via simple transformations - \*/ - matrixproto.split = function () { - var out = {}; - // translation - out.dx = this.e; - out.dy = this.f; - - // scale and shear - var row = [[this.a, this.c], [this.b, this.d]]; - out.scalex = math.sqrt(norm(row[0])); - normalize(row[0]); - - out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1]; - row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear]; - - out.scaley = math.sqrt(norm(row[1])); - normalize(row[1]); - out.shear /= out.scaley; - - if (this.determinant() < 0) { - out.scalex = -out.scalex; - } - - // rotation - var sin = -row[0][1], - cos = row[1][1]; - if (cos < 0) { - out.rotate = deg(math.acos(cos)); - if (sin < 0) { - out.rotate = 360 - out.rotate; - } - } else { - out.rotate = deg(math.asin(sin)); - } - - out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate); - out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate; - out.noRotation = !+out.shear.toFixed(9) && !out.rotate; - return out; - }; - /*\ - * Matrix.toTransformString - [ method ] - ** - * Returns transform string that represents given matrix - = (string) transform string - \*/ - matrixproto.toTransformString = function (shorter) { - var s = shorter || this.split(); - if (!+s.shear.toFixed(9)) { - s.scalex = +s.scalex.toFixed(4); - s.scaley = +s.scaley.toFixed(4); - s.rotate = +s.rotate.toFixed(4); - return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) + - (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) + - (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E); - } else { - return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)]; - } - }; -})(Matrix.prototype); -/*\ - * Snap.Matrix - [ method ] - ** - * Utility method - ** - * Returns a matrix based on the given parameters - - a (number) - - b (number) - - c (number) - - d (number) - - e (number) - - f (number) - * or - - svgMatrix (SVGMatrix) - = (object) @Matrix -\*/ -Snap.Matrix = Matrix; // Colour /*\ * Snap.getRGB @@ -1936,7 +1635,7 @@ Snap._.svgTransform2string = svgTransform2string; Snap._.rgTransform = new RegExp("^[a-z][" + spaces + "]*-?\\.?\\d", "i"); function transform2matrix(tstr, bbox) { var tdata = parseTransformString(tstr), - m = new Matrix; + m = new Snap.Matrix; if (tdata) { for (var i = 0, ii = tdata.length; i < ii; i++) { var t = tdata[i], @@ -2014,7 +1713,7 @@ function extractTransform(el, tstr) { tstr = el.node.getAttribute("transform"); } if (!tstr) { - return new Matrix; + return new Snap.Matrix; } tstr = svgTransform2string(tstr); } else { @@ -2304,8 +2003,6 @@ function arrayFirstValue(arr) { } return el; }; -// SIERRA Element.getBBox(): Unclear why you would want to express the dimension of the box as a path. -// SIERRA Element.getBBox(): Unclear why you would want to use r0/r1/r2. Also, basic definitions: wouldn't the _smallest circle that can be enclosed_ be a zero-radius point? /*\ * Element.getBBox [ method ] @@ -2382,15 +2079,15 @@ function arrayFirstValue(arr) { var _ = this._; if (tstr == null) { var papa = this, - global = new Matrix(this.node.getCTM()), + global = new Snap.Matrix(this.node.getCTM()), local = extractTransform(this), ms = [local], - m = new Matrix, + m = new Snap.Matrix, i, localString = local.toTransformString(), string = Str(local) == Str(this.matrix) ? _.transform : localString; - while ((papa = papa.parent()) && papa.type != "svg") { + while (papa.type != "svg" && (papa = papa.parent())) { ms.push(extractTransform(papa)); } i = ms.length; @@ -2409,7 +2106,7 @@ function arrayFirstValue(arr) { toString: propString }; } - if (tstr instanceof Matrix) { + if (tstr instanceof Snap.Matrix) { this.matrix = tstr; } else { extractTransform(this, tstr); @@ -3277,7 +2974,6 @@ function arrayFirstValue(arr) { }; } }(Element.prototype)); -// SIERRA Snap.parse() accepts & returns a fragment, but there's no info on what it does in between. What if it doesn't parse? /*\ * Snap.parse [ method ] @@ -3406,1026 +3102,58 @@ function wrap(dom) { if (dom instanceof Element || dom instanceof Fragment) { return dom; } - if (dom.tagName == "svg") { + if (dom.tagName && dom.tagName.toLowerCase() == "svg") { return new Paper(dom); } - if (dom.tagName.toLowerCase() == "object" && dom.type == "image/svg+xml") { + if (dom.tagName && dom.tagName.toLowerCase() == "object" && dom.type == "image/svg+xml") { return new Paper(dom.contentDocument.getElementsByTagName("svg")[0]); } return new Element(dom); } -// gradients' helpers -function Gstops() { - return this.selectAll("stop"); -} -function GaddStop(color, offset) { - var stop = $("stop"), - attr = { - offset: +offset + "%" - }; - color = Snap.color(color); - attr["stop-color"] = color.hex; - if (color.opacity < 1) { - attr["stop-opacity"] = color.opacity; - } - $(stop, attr); - this.node.appendChild(stop); - return this; -} -function GgetBBox() { - if (this.type == "linearGradient") { - var x1 = $(this.node, "x1") || 0, - x2 = $(this.node, "x2") || 1, - y1 = $(this.node, "y1") || 0, - y2 = $(this.node, "y2") || 0; - return Snap._.box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1)); - } else { - var cx = this.node.cx || .5, - cy = this.node.cy || .5, - r = this.node.r || 0; - return Snap._.box(cx - r, cy - r, r * 2, r * 2); - } -} -function gradient(defs, str) { - var grad = arrayFirstValue(eve("snap.util.grad.parse", null, str)), - el; - if (!grad) { - return null; - } - grad.params.unshift(defs); - if (grad.type.toLowerCase() == "l") { - el = gradientLinear.apply(0, grad.params); - } else { - el = gradientRadial.apply(0, grad.params); - } - if (grad.type != grad.type.toLowerCase()) { - $(el.node, { - gradientUnits: "userSpaceOnUse" - }); - } - var stops = grad.stops, - len = stops.length, - start = 0, - j = 0; - function seed(i, end) { - var step = (end - start) / (i - j); - for (var k = j; k < i; k++) { - stops[k].offset = +(+start + step * (k - j)).toFixed(2); - } - j = i; - start = end; - } - len--; - for (var i = 0; i < len; i++) if ("offset" in stops[i]) { - seed(i, stops[i].offset); - } - stops[len].offset = stops[len].offset || 100; - seed(len, stops[len].offset); - for (i = 0; i <= len; i++) { - var stop = stops[i]; - el.addStop(stop.color, stop.offset); - } - return el; -} -function gradientLinear(defs, x1, y1, x2, y2) { - var el = make("linearGradient", defs); - el.stops = Gstops; - el.addStop = GaddStop; - el.getBBox = GgetBBox; - if (x1 != null) { - $(el.node, { - x1: x1, - y1: y1, - x2: x2, - y2: y2 - }); - } - return el; -} -function gradientRadial(defs, cx, cy, r, fx, fy) { - var el = make("radialGradient", defs); - el.stops = Gstops; - el.addStop = GaddStop; - el.getBBox = GgetBBox; - if (cx != null) { - $(el.node, { - cx: cx, - cy: cy, - r: r - }); - } - if (fx != null && fy != null) { - $(el.node, { - fx: fx, - fy: fy - }); - } - return el; -} -// Paper prototype methods -(function (proto) { - /*\ - * Paper.el - [ method ] - ** - * Creates an element on paper with a given name and no attributes - ** - - name (string) tag name - - attr (object) attributes - = (Element) the current element - > Usage - | var c = paper.circle(10, 10, 10); // is the same as... - | var c = paper.el("circle").attr({ - | cx: 10, - | cy: 10, - | r: 10 - | }); - | // and the same as - | var c = paper.el("circle", { - | cx: 10, - | cy: 10, - | r: 10 - | }); - \*/ - proto.el = function (name, attr) { - return make(name, this.node).attr(attr); - }; - /*\ - * Paper.rect - [ method ] - * - * Draws a rectangle - ** - - x (number) x coordinate of the top left corner - - y (number) y coordinate of the top left corner - - width (number) width - - height (number) height - - rx (number) #optional horizontal radius for rounded corners, default is 0 - - ry (number) #optional vertical radius for rounded corners, default is rx or 0 - = (object) the `rect` element - ** - > Usage - | // regular rectangle - | var c = paper.rect(10, 10, 50, 50); - | // rectangle with rounded corners - | var c = paper.rect(40, 40, 50, 50, 10); - \*/ - proto.rect = function (x, y, w, h, rx, ry) { - var attr; - if (ry == null) { - ry = rx; - } - if (is(x, "object") && x == "[object Object]") { - attr = x; - } else if (x != null) { - attr = { - x: x, - y: y, - width: w, - height: h - }; - if (rx != null) { - attr.rx = rx; - attr.ry = ry; - } - } - return this.el("rect", attr); - }; - /*\ - * Paper.circle - [ method ] - ** - * Draws a circle - ** - - x (number) x coordinate of the centre - - y (number) y coordinate of the centre - - r (number) radius - = (object) the `circle` element - ** - > Usage - | var c = paper.circle(50, 50, 40); - \*/ - proto.circle = function (cx, cy, r) { - var attr; - if (is(cx, "object") && cx == "[object Object]") { - attr = cx; - } else if (cx != null) { - attr = { - cx: cx, - cy: cy, - r: r - }; - } - return this.el("circle", attr); - }; - /*\ - * Paper.image - [ method ] - ** - * Places an image on the surface - ** - - src (string) URI of the source image - - x (number) x offset position - - y (number) y offset position - - width (number) width of the image - - height (number) height of the image - = (object) the `image` element - * or - = (object) Snap element object with type `image` - ** - > Usage - | var c = paper.image("apple.png", 10, 10, 80, 80); - \*/ - proto.image = function (src, x, y, width, height) { - var el = make("image", this.node); - if (is(src, "object") && "src" in src) { - el.attr(src); - } else if (src != null) { - var set = { - "xlink:href": src, - preserveAspectRatio: "none" - }; - if (x != null && y != null) { - set.x = x; - set.y = y; - } - if (width != null && height != null) { - set.width = width; - set.height = height; - } else { - preload(src, function () { - $(el.node, { - width: this.offsetWidth, - height: this.offsetHeight - }); - }); - } - $(el.node, set); - } - return el; - }; - /*\ - * Paper.ellipse - [ method ] - ** - * Draws an ellipse - ** - - x (number) x coordinate of the centre - - y (number) y coordinate of the centre - - rx (number) horizontal radius - - ry (number) vertical radius - = (object) the `ellipse` element - ** - > Usage - | var c = paper.ellipse(50, 50, 40, 20); - \*/ - proto.ellipse = function (cx, cy, rx, ry) { - var el = make("ellipse", this.node); - if (is(cx, "object") && cx == "[object Object]") { - el.attr(cx); - } else if (cx != null) { - el.attr({ - cx: cx, - cy: cy, - rx: rx, - ry: ry - }); - } - return el; - }; - // SIERRA Paper.path(): Unclear from the link what a Catmull-Rom curveto is, and why it would make life any easier. - /*\ - * Paper.path - [ method ] - ** - * Creates a `` element using the given string as the path's definition - - pathString (string) #optional path string in SVG format - * Path string consists of one-letter commands, followed by comma seprarated arguments in numerical form. Example: - | "M10,20L30,40" - * This example features two commands: `M`, with arguments `(10, 20)` and `L` with arguments `(30, 40)`. Uppercase letter commands express coordinates in absolute terms, while lowercase commands express them in relative terms from the most recently declared coordinates. - * - #

Here is short list of commands available, for more details see SVG path string format or article about path strings at MDN.

- # - # - # - # - # - # - # - # - # - # - # - #
CommandNameParameters
Mmoveto(x y)+
Zclosepath(none)
Llineto(x y)+
Hhorizontal linetox+
Vvertical linetoy+
Ccurveto(x1 y1 x2 y2 x y)+
Ssmooth curveto(x2 y2 x y)+
Qquadratic Bézier curveto(x1 y1 x y)+
Tsmooth quadratic Bézier curveto(x y)+
Aelliptical arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
RCatmull-Rom curveto*x1 y1 (x y)+
- * * _Catmull-Rom curveto_ is a not standard SVG command and added to make life easier. - * Note: there is a special case when a path consists of only three commands: `M10,10R…z`. In this case the path connects back to its starting point. - > Usage - | var c = paper.path("M10 10L90 90"); - | // draw a diagonal line: - | // move to 10,10, line to 90,90 - \*/ - proto.path = function (d) { - var el = make("path", this.node); - if (is(d, "object") && !is(d, "array")) { - el.attr(d); - } else if (d) { - el.attr({ - d: d - }); - } - return el; - }; - /*\ - * Paper.g - [ method ] - ** - * Creates a group element - ** - - varargs (…) #optional elements to nest within the group - = (object) the `g` element - ** - > Usage - | var c1 = paper.circle(), - | c2 = paper.rect(), - | g = paper.g(c2, c1); // note that the order of elements is different - * or - | var c1 = paper.circle(), - | c2 = paper.rect(), - | g = paper.g(); - | g.add(c2, c1); - \*/ - /*\ - * Paper.group - [ method ] - ** - * See @Paper.g - \*/ - proto.group = proto.g = function (first) { - var el = make("g", this.node); - if (arguments.length == 1 && first && !first.type) { - el.attr(first); - } else if (arguments.length) { - el.add(Array.prototype.slice.call(arguments, 0)); - } - return el; - }; - /*\ - * Paper.svg - [ method ] - ** - * Creates a nested SVG element. - - x (number) @optional X of the element - - y (number) @optional Y of the element - - width (number) @optional width of the element - - height (number) @optional height of the element - - vbx (number) @optional viewbox X - - vby (number) @optional viewbox Y - - vbw (number) @optional viewbox width - - vbh (number) @optional viewbox height - ** - = (object) the `svg` element - ** - \*/ - proto.svg = function (x, y, width, height, vbx, vby, vbw, vbh) { - var el = make("svg", this.node), - attrs = {}; - if (is(x, "object") && y == null) { - attrs = x; - } else { - if (x != null) { - attrs.x = x; - } - if (y != null) { - attrs.y = y; - } - if (width != null) { - attrs.width = width; - } - if (height != null) { - attrs.height = height; - } - if (vbx != null && vby != null && vbw != null && vbh != null) { - attrs.viewBox = [vbx, vby, vbw, vbh]; - } - } - el.attr(attrs); - return el; - }; - /*\ - * Paper.mask - [ method ] - ** - * Equivalent in behaviour to @Paper.g, except it’s a mask. - ** - = (object) the `mask` element - ** - \*/ - proto.mask = function (first) { - var el = make("mask", this.node); - if (arguments.length == 1 && first && !first.type) { - el.attr(first); - } else if (arguments.length) { - el.add(Array.prototype.slice.call(arguments, 0)); - } - return el; - }; - /*\ - * Paper.ptrn - [ method ] - ** - * Equivalent in behaviour to @Paper.g, except it’s a mask. - - x (number) @optional X of the element - - y (number) @optional Y of the element - - width (number) @optional width of the element - - height (number) @optional height of the element - - vbx (number) @optional viewbox X - - vby (number) @optional viewbox Y - - vbw (number) @optional viewbox width - - vbh (number) @optional viewbox height - ** - = (object) the `mask` element - ** - \*/ - proto.ptrn = function (x, y, width, height, vx, vy, vw, vh) { - var el = make("pattern", this.node); - if (!arguments.length) { - var attr = {patternUnits: "userSpaceOnUse"}; - } else { - if (vx == null) { - vx = x; - vy = y; - vw = width; - vh = height; - } - attr = { - x: x, - y: y, - width: width, - height: height, - patternUnits: "userSpaceOnUse", - viewBox: [vx, vy, vw, vh].join(" ") - }; - } - if (is(x, "object")) { - attr = x; - } - el.attr(attr); - return el; - }; - /*\ - * Paper.use - [ method ] - ** - * Creates a element. - - id (string) @optional id of element to link - * or - - id (Element) @optional element to link - ** - = (object) the `use` element - ** - \*/ - proto.use = function (id) { - if (id != null) { - var el = make("use", this.node); - if (id instanceof Element) { - if (!id.attr("id")) { - id.attr({id: ID()}); - } - id = id.attr("id"); - } - id && el.attr({ - "xlink:href": id - }); - return el; - } else { - return Element.prototype.use.call(this); - } - }; - /*\ - * Paper.text - [ method ] - ** - * Draws a text string - ** - - x (number) x coordinate position - - y (number) y coordinate position - - text (string|array) The text string to draw or array of strings to nest within separate `` elements - = (object) the `text` element - ** - > Usage - | var t1 = paper.text(50, 50, "Snap"); - | var t2 = paper.text(50, 50, ["S","n","a","p"]); - | // Text path usage - | t1.attr({textpath: "M10,10L100,100"}); - | // or - | var pth = paper.path("M10,10L100,100"); - | t1.attr({textpath: pth}); - \*/ - proto.text = function (x, y, text) { - var el = make("text", this.node); - if (is(x, "object")) { - el.attr(x); - } else if (x != null) { - el.attr({ - x: x, - y: y, - text: text || "" - }); - } - return el; - }; - /*\ - * Paper.line - [ method ] - ** - * Draws a line - ** - - x1 (number) x coordinate position of the start - - y1 (number) y coordinate position of the start - - x2 (number) x coordinate position of the end - - y2 (number) y coordinate position of the end - = (object) the `line` element - ** - > Usage - | var t1 = paper.line(50, 50, 100, 100); - \*/ - proto.line = function (x1, y1, x2, y2) { - var el = make("line", this.node); - if (is(x1, "object")) { - el.attr(x1); - } else if (x1 != null) { - el.attr({ - x1: x1, - x2: x2, - y1: y1, - y2: y2 - }); - } - return el; - }; - /*\ - * Paper.polyline - [ method ] - ** - * Draws a polyline - ** - - points (array) array of points - * or - - varargs (…) points - = (object) the `polyline` element - ** - > Usage - | var p1 = paper.polyline([10, 10, 100, 100]); - | var p2 = paper.polyline(10, 10, 100, 100); - \*/ - proto.polyline = function (points) { - if (arguments.length > 1) { - points = Array.prototype.slice.call(arguments, 0); - } - var el = make("polyline", this.node); - if (is(points, "object") && !is(points, "array")) { - el.attr(points); - } else if (points != null) { - el.attr({ - points: points - }); - } - return el; - }; - /*\ - * Paper.polygon - [ method ] - ** - * Draws a polygon. See @Paper.polyline - \*/ - proto.polygon = function (points) { - if (arguments.length > 1) { - points = Array.prototype.slice.call(arguments, 0); - } - var el = make("polygon", this.node); - if (is(points, "object") && !is(points, "array")) { - el.attr(points); - } else if (points != null) { - el.attr({ - points: points - }); - } - return el; - }; - // gradients - (function () { - /*\ - * Paper.gradient - [ method ] - ** - * Creates a gradient element - ** - - gradient (string) gradient descriptor - > Gradient Descriptor - * The gradient descriptor is an expression formatted as - * follows: `()`. The `` can be - * either linear or radial. The uppercase `L` or `R` letters - * indicate absolute coordinates offset from the SVG surface. - * Lowercase `l` or `r` letters indicate coordinates - * calculated relative to the element to which the gradient is - * applied. Coordinates specify a linear gradient vector as - * `x1`, `y1`, `x2`, `y2`, or a radial gradient as `cx`, `cy`, - * `r` and optional `fx`, `fy` specifying a focal point away - * from the center of the circle. Specify `` as a list - * of dash-separated CSS color values. Each color may be - * followed by a custom offset value, separated with a colon - * character. - > Examples - * Linear gradient, relative from top-left corner to bottom-right - * corner, from black through red to white: - | var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff"); - * Linear gradient, absolute from (0, 0) to (100, 100), from black - * through red at 25% to white: - | var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff"); - * Radial gradient, relative from the center of the element with radius - * half the width, from black to white: - | var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff"); - * To apply the gradient: - | paper.circle(50, 50, 40).attr({ - | fill: g - | }); - = (object) the `gradient` element - \*/ - proto.gradient = function (str) { - return gradient(this.defs, str); - }; - proto.gradientLinear = function (x1, y1, x2, y2) { - return gradientLinear(this.defs, x1, y1, x2, y2); - }; - proto.gradientRadial = function (cx, cy, r, fx, fy) { - return gradientRadial(this.defs, cx, cy, r, fx, fy); - }; - /*\ - * Paper.toString - [ method ] - ** - * Returns SVG code for the @Paper - = (string) SVG code for the @Paper - \*/ - proto.toString = function () { - var f = glob.doc.createDocumentFragment(), - d = glob.doc.createElement("div"), - svg = this.node.cloneNode(true), - res; - f.appendChild(d); - d.appendChild(svg); - $(svg, {xmlns: xmlns}); - res = d.innerHTML; - f.removeChild(f.firstChild); - return res; - }; - /*\ - * Paper.clear - [ method ] - ** - * Removes all child nodes of the paper, except . - \*/ - proto.clear = function () { - var node = this.node.firstChild, - next; - while (node) { - next = node.nextSibling; - if (node.tagName != "defs") { - node.parentNode.removeChild(node); - } - node = next; - } - }; - }()); -}(Paper.prototype)); - -// simple ajax +Snap._.make = make; +Snap._.wrap = wrap; /*\ - * Snap.ajax + * Paper.el [ method ] ** - * Simple implementation of Ajax + * Creates an element on paper with a given name and no attributes ** - - url (string) URL - - postData (object|string) data for post request - - callback (function) callback - - scope (object) #optional scope of callback - * or - - url (string) URL - - callback (function) callback - - scope (object) #optional scope of callback - = (XMLHttpRequest) the XMLHttpRequest object, just in case + - name (string) tag name + - attr (object) attributes + = (Element) the current element + > Usage + | var c = paper.circle(10, 10, 10); // is the same as... + | var c = paper.el("circle").attr({ + | cx: 10, + | cy: 10, + | r: 10 + | }); + | // and the same as + | var c = paper.el("circle", { + | cx: 10, + | cy: 10, + | r: 10 + | }); \*/ -Snap.ajax = function (url, postData, callback, scope){ - var req = new XMLHttpRequest, - id = ID(); - if (req) { - if (is(postData, "function")) { - scope = callback; - callback = postData; - postData = null; - } else if (is(postData, "object")) { - var pd = []; - for (var key in postData) if (postData.hasOwnProperty(key)) { - pd.push(encodeURIComponent(key) + "=" + encodeURIComponent(postData[key])); - } - postData = pd.join("&"); - } - req.open((postData ? "POST" : "GET"), url, true); - req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - if (postData) { - req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - } - if (callback) { - eve.once("snap.ajax." + id + ".0", callback); - eve.once("snap.ajax." + id + ".200", callback); - eve.once("snap.ajax." + id + ".304", callback); - } - req.onreadystatechange = function() { - if (req.readyState != 4) return; - eve("snap.ajax." + id + "." + req.status, scope, req); - }; - if (req.readyState == 4) { - return req; - } - req.send(postData); - return req; - } +Paper.prototype.el = function (name, attr) { + var el = make(name, this.node); + attr && el.attr(attr); + return el; }; -/*\ - * Snap.load - [ method ] - ** - * Loads external SVG file as a @Fragment (see @Snap.ajax for more advanced AJAX) - ** - - url (string) URL - - callback (function) callback - - scope (object) #optional scope of callback -\*/ -Snap.load = function (url, callback, scope) { - Snap.ajax(url, function (req) { - var f = Snap.parse(req.responseText); - scope ? callback.call(scope, f) : callback(f); - }); -}; - -// Attributes event handlers -eve.on("snap.util.attr.mask", function (value) { - if (value instanceof Element || value instanceof Fragment) { - eve.stop(); - if (value instanceof Fragment && value.node.childNodes.length == 1) { - value = value.node.firstChild; - getSomeDefs(this).appendChild(value); - value = wrap(value); - } - if (value.type == "mask") { - var mask = value; - } else { - mask = make("mask", getSomeDefs(this)); - mask.node.appendChild(value.node); - !mask.node.id && $(mask.node, { - id: mask.id - }); - } - $(this.node, { - mask: URL(mask.id) - }); - } -}); -(function (clipIt) { - eve.on("snap.util.attr.clip", clipIt); - eve.on("snap.util.attr.clip-path", clipIt); - eve.on("snap.util.attr.clipPath", clipIt); -}(function (value) { - if (value instanceof Element || value instanceof Fragment) { - eve.stop(); - if (value.type == "clipPath") { - var clip = value; - } else { - clip = make("clipPath", getSomeDefs(this)); - clip.node.appendChild(value.node); - !clip.node.id && $(clip.node, { - id: clip.id - }); - } - $(this.node, { - "clip-path": URL(clip.id) - }); - } -})); -function fillStroke(name) { - return function (value) { - eve.stop(); - if (value instanceof Fragment && value.node.childNodes.length == 1 && - (value.node.firstChild.tagName == "radialGradient" || - value.node.firstChild.tagName == "linearGradient" || - value.node.firstChild.tagName == "pattern")) { - value = value.node.firstChild; - getSomeDefs(this).appendChild(value); - value = wrap(value); - } - if (value instanceof Element) { - if (value.type == "radialGradient" || value.type == "linearGradient" - || value.type == "pattern") { - if (!value.node.id) { - $(value.node, { - id: value.id - }); - } - var fill = URL(value.node.id); - } else { - fill = value.attr(name); - } - } else { - fill = Snap.color(value); - if (fill.error) { - var grad = gradient(getSomeDefs(this), value); - if (grad) { - if (!grad.node.id) { - $(grad.node, { - id: grad.id - }); - } - fill = URL(grad.node.id); - } else { - fill = value; - } - } else { - fill = Str(fill); - } - } - var attrs = {}; - attrs[name] = fill; - $(this.node, attrs); - this.node.style[name] = E; - }; -} -eve.on("snap.util.attr.fill", fillStroke("fill")); -eve.on("snap.util.attr.stroke", fillStroke("stroke")); -var gradrg = /^([lr])(?:\(([^)]*)\))?(.*)$/i; -eve.on("snap.util.grad.parse", function parseGrad(string) { - string = Str(string); - var tokens = string.match(gradrg); - if (!tokens) { - return null; - } - var type = tokens[1], - params = tokens[2], - stops = tokens[3]; - params = params.split(/\s*,\s*/).map(function (el) { - return +el == el ? +el : el; - }); - if (params.length == 1 && params[0] == 0) { - params = []; - } - stops = stops.split("-"); - stops = stops.map(function (el) { - el = el.split(":"); - var out = { - color: el[0] - }; - if (el[1]) { - out.offset = parseFloat(el[1]); - } - return out; - }); - return { - type: type, - params: params, - stops: stops - }; -}); - -eve.on("snap.util.attr.d", function (value) { - eve.stop(); - if (is(value, "array") && is(value[0], "array")) { - value = Snap.path.toString.call(value); - } - value = Str(value); - if (value.match(/[ruo]/i)) { - value = Snap.path.toAbsolute(value); - } - $(this.node, {d: value}); -})(-1); -eve.on("snap.util.attr.#text", function (value) { - eve.stop(); - value = Str(value); - var txt = glob.doc.createTextNode(value); - while (this.node.firstChild) { - this.node.removeChild(this.node.firstChild); - } - this.node.appendChild(txt); -})(-1); -eve.on("snap.util.attr.path", function (value) { - eve.stop(); - this.attr({d: value}); -})(-1); -eve.on("snap.util.attr.class", function (value) { - eve.stop(); - this.node.className.baseVal = value; -})(-1); -eve.on("snap.util.attr.viewBox", function (value) { - var vb; - if (is(value, "object") && "x" in value) { - vb = [value.x, value.y, value.width, value.height].join(" "); - } else if (is(value, "array")) { - vb = value.join(" "); - } else { - vb = value; - } - $(this.node, { - viewBox: vb - }); - eve.stop(); -})(-1); -eve.on("snap.util.attr.transform", function (value) { - this.transform(value); - eve.stop(); -})(-1); -eve.on("snap.util.attr.r", function (value) { - if (this.type == "rect") { - eve.stop(); - $(this.node, { - rx: value, - ry: value - }); - } -})(-1); -eve.on("snap.util.attr.textpath", function (value) { - eve.stop(); - if (this.type == "text") { - var id, tp, node; - if (!value && this.textPath) { - tp = this.textPath; - while (tp.node.firstChild) { - this.node.appendChild(tp.node.firstChild); - } - tp.remove(); - delete this.textPath; - return; - } - if (is(value, "string")) { - var defs = getSomeDefs(this), - path = wrap(defs.parentNode).path(value); - defs.appendChild(path.node); - id = path.id; - path.attr({id: id}); - } else { - value = wrap(value); - if (value instanceof Element) { - id = value.attr("id"); - if (!id) { - id = value.id; - value.attr({id: id}); - } - } - } - if (id) { - tp = this.textPath; - node = this.node; - if (tp) { - tp.attr({"xlink:href": "#" + id}); - } else { - tp = $("textPath", { - "xlink:href": "#" + id - }); - while (node.firstChild) { - tp.appendChild(node.firstChild); - } - node.appendChild(tp); - this.textPath = wrap(tp); - } - } - } -})(-1); -eve.on("snap.util.attr.text", function (value) { - if (this.type == "text") { - var i = 0, - node = this.node, - tuner = function (chunk) { - var out = $("tspan"); - if (is(chunk, "array")) { - for (var i = 0; i < chunk.length; i++) { - out.appendChild(tuner(chunk[i])); - } - } else { - out.appendChild(glob.doc.createTextNode(chunk)); - } - out.normalize && out.normalize(); - return out; - }; - while (node.firstChild) { - node.removeChild(node.firstChild); - } - var tuned = tuner(value); - while (tuned.firstChild) { - node.appendChild(tuned.firstChild); - } - } - eve.stop(); -})(-1); // default +eve.on("snap.util.getattr", function () { + var att = eve.nt(); + att = att.substring(att.lastIndexOf(".") + 1); + var css = att.replace(/[A-Z]/g, function (letter) { + return "-" + letter.toLowerCase(); + }); + if (cssAttr[has](css)) { + return this.node.ownerDocument.defaultView.getComputedStyle(this.node, null).getPropertyValue(css); + } else { + return $(this.node, att); + } +}); var cssAttr = { "alignment-baseline": 0, "baseline-shift": 0, @@ -4507,134 +3235,77 @@ eve.on("snap.util.attr", function (value) { $(this.node, attr); } }); -eve.on("snap.util.getattr.transform", function () { - eve.stop(); - return this.transform(); -})(-1); -eve.on("snap.util.getattr.textpath", function () { - eve.stop(); - return this.textPath; -})(-1); -// Markers -(function () { - function getter(end) { - return function () { - eve.stop(); - var style = glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue("marker-" + end); - if (style == "none") { - return style; - } else { - return Snap(glob.doc.getElementById(style.match(reURLValue)[1])); +(function (proto) {}(Paper.prototype)); + +// simple ajax +/*\ + * Snap.ajax + [ method ] + ** + * Simple implementation of Ajax + ** + - url (string) URL + - postData (object|string) data for post request + - callback (function) callback + - scope (object) #optional scope of callback + * or + - url (string) URL + - callback (function) callback + - scope (object) #optional scope of callback + = (XMLHttpRequest) the XMLHttpRequest object, just in case +\*/ +Snap.ajax = function (url, postData, callback, scope){ + var req = new XMLHttpRequest, + id = ID(); + if (req) { + if (is(postData, "function")) { + scope = callback; + callback = postData; + postData = null; + } else if (is(postData, "object")) { + var pd = []; + for (var key in postData) if (postData.hasOwnProperty(key)) { + pd.push(encodeURIComponent(key) + "=" + encodeURIComponent(postData[key])); } - }; - } - function setter(end) { - return function (value) { - eve.stop(); - var name = "marker" + end.charAt(0).toUpperCase() + end.substring(1); - if (value == "" || !value) { - this.node.style[name] = "none"; - return; - } - if (value.type == "marker") { - var id = value.node.id; - if (!id) { - $(value.node, {id: value.id}); - } - this.node.style[name] = URL(id); - return; - } - }; - } - eve.on("snap.util.getattr.marker-end", getter("end"))(-1); - eve.on("snap.util.getattr.markerEnd", getter("end"))(-1); - eve.on("snap.util.getattr.marker-start", getter("start"))(-1); - eve.on("snap.util.getattr.markerStart", getter("start"))(-1); - eve.on("snap.util.getattr.marker-mid", getter("mid"))(-1); - eve.on("snap.util.getattr.markerMid", getter("mid"))(-1); - eve.on("snap.util.attr.marker-end", setter("end"))(-1); - eve.on("snap.util.attr.markerEnd", setter("end"))(-1); - eve.on("snap.util.attr.marker-start", setter("start"))(-1); - eve.on("snap.util.attr.markerStart", setter("start"))(-1); - eve.on("snap.util.attr.marker-mid", setter("mid"))(-1); - eve.on("snap.util.attr.markerMid", setter("mid"))(-1); -}()); -eve.on("snap.util.getattr.r", function () { - if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) { - eve.stop(); - return $(this.node, "rx"); - } -})(-1); -function textExtract(node) { - var out = []; - var children = node.childNodes; - for (var i = 0, ii = children.length; i < ii; i++) { - var chi = children[i]; - if (chi.nodeType == 3) { - out.push(chi.nodeValue); + postData = pd.join("&"); } - if (chi.tagName == "tspan") { - if (chi.childNodes.length == 1 && chi.firstChild.nodeType == 3) { - out.push(chi.firstChild.nodeValue); - } else { - out.push(textExtract(chi)); - } + req.open((postData ? "POST" : "GET"), url, true); + if (postData) { + req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); } + if (callback) { + eve.once("snap.ajax." + id + ".0", callback); + eve.once("snap.ajax." + id + ".200", callback); + eve.once("snap.ajax." + id + ".304", callback); + } + req.onreadystatechange = function() { + if (req.readyState != 4) return; + eve("snap.ajax." + id + "." + req.status, scope, req); + }; + if (req.readyState == 4) { + return req; + } + req.send(postData); + return req; } - return out; -} -eve.on("snap.util.getattr.text", function () { - if (this.type == "text" || this.type == "tspan") { - eve.stop(); - var out = textExtract(this.node); - return out.length == 1 ? out[0] : out; - } -})(-1); -eve.on("snap.util.getattr.#text", function () { - return this.node.textContent; -})(-1); -eve.on("snap.util.getattr.viewBox", function () { - eve.stop(); - var vb = $(this.node, "viewBox"); - if (vb) { - vb = vb.split(separator); - return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]); - } else { - return; - } -})(-1); -eve.on("snap.util.getattr.points", function () { - var p = $(this.node, "points"); - eve.stop(); - return p.split(separator); -}); -eve.on("snap.util.getattr.path", function () { - var p = $(this.node, "d"); - eve.stop(); - return p; -}); -eve.on("snap.util.getattr.class", function () { - return this.node.className.baseVal; -}); -function getFontSize() { - eve.stop(); - return this.node.style.fontSize; -} -eve.on("snap.util.getattr.fontSize", getFontSize)(-1); -eve.on("snap.util.getattr.font-size", getFontSize)(-1); -// default -eve.on("snap.util.getattr", function () { - var att = eve.nt(); - att = att.substring(att.lastIndexOf(".") + 1); - var css = att.replace(/[A-Z]/g, function (letter) { - return "-" + letter.toLowerCase(); +}; +/*\ + * Snap.load + [ method ] + ** + * Loads external SVG file as a @Fragment (see @Snap.ajax for more advanced AJAX) + ** + - url (string) URL + - callback (function) callback + - scope (object) #optional scope of callback +\*/ +Snap.load = function (url, callback, scope) { + Snap.ajax(url, function (req) { + var f = Snap.parse(req.responseText); + scope ? callback.call(scope, f) : callback(f); }); - if (cssAttr[has](css)) { - return glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue(css); - } else { - return $(this.node, att); - } -}); +}; var getOffset = function (elem) { var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, @@ -4685,7 +3356,7 @@ Snap.getElementByPoint = function (x, y) { [ method ] ** * Let you write plugins. You pass in a function with four arguments, like this: - | Snap.plugin(function (Snap, Element, Paper, global) { + | Snap.plugin(function (Snap, Element, Paper, global, Fragment) { | Snap.newmethod = function () {}; | Element.prototype.newmethod = function () {}; | Paper.prototype.newmethod = function () {}; @@ -4696,12 +3367,1402 @@ Snap.getElementByPoint = function (x, y) { - f (function) your plugin body \*/ Snap.plugin = function (f) { - f(Snap, Element, Paper, glob); + f(Snap, Element, Paper, glob, Fragment); }; glob.win.Snap = Snap; return Snap; }()); +// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { + var objectToString = Object.prototype.toString, + Str = String, + math = Math, + E = ""; + function Matrix(a, b, c, d, e, f) { + if (b == null && objectToString.call(a) == "[object SVGMatrix]") { + this.a = a.a; + this.b = a.b; + this.c = a.c; + this.d = a.d; + this.e = a.e; + this.f = a.f; + return; + } + if (a != null) { + this.a = +a; + this.b = +b; + this.c = +c; + this.d = +d; + this.e = +e; + this.f = +f; + } else { + this.a = 1; + this.b = 0; + this.c = 0; + this.d = 1; + this.e = 0; + this.f = 0; + } + } + (function (matrixproto) { + /*\ + * Matrix.add + [ method ] + ** + * Adds the given matrix to existing one + - a (number) + - b (number) + - c (number) + - d (number) + - e (number) + - f (number) + * or + - matrix (object) @Matrix + \*/ + matrixproto.add = function (a, b, c, d, e, f) { + var out = [[], [], []], + m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], + matrix = [[a, c, e], [b, d, f], [0, 0, 1]], + x, y, z, res; + + if (a && a instanceof Matrix) { + matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]; + } + + for (x = 0; x < 3; x++) { + for (y = 0; y < 3; y++) { + res = 0; + for (z = 0; z < 3; z++) { + res += m[x][z] * matrix[z][y]; + } + out[x][y] = res; + } + } + this.a = out[0][0]; + this.b = out[1][0]; + this.c = out[0][1]; + this.d = out[1][1]; + this.e = out[0][2]; + this.f = out[1][2]; + return this; + }; + /*\ + * Matrix.invert + [ method ] + ** + * Returns an inverted version of the matrix + = (object) @Matrix + \*/ + matrixproto.invert = function () { + var me = this, + x = me.a * me.d - me.b * me.c; + return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x); + }; + /*\ + * Matrix.clone + [ method ] + ** + * Returns a copy of the matrix + = (object) @Matrix + \*/ + matrixproto.clone = function () { + return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f); + }; + /*\ + * Matrix.translate + [ method ] + ** + * Translate the matrix + - x (number) horizontal offset distance + - y (number) vertical offset distance + \*/ + matrixproto.translate = function (x, y) { + return this.add(1, 0, 0, 1, x, y); + }; + /*\ + * Matrix.scale + [ method ] + ** + * Scales the matrix + - x (number) amount to be scaled, with `1` resulting in no change + - y (number) #optional amount to scale along the vertical axis. (Otherwise `x` applies to both axes.) + - cx (number) #optional horizontal origin point from which to scale + - cy (number) #optional vertical origin point from which to scale + * Default cx, cy is the middle point of the element. + \*/ + matrixproto.scale = function (x, y, cx, cy) { + y == null && (y = x); + (cx || cy) && this.add(1, 0, 0, 1, cx, cy); + this.add(x, 0, 0, y, 0, 0); + (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy); + return this; + }; + /*\ + * Matrix.rotate + [ method ] + ** + * Rotates the matrix + - a (number) angle of rotation, in degrees + - x (number) horizontal origin point from which to rotate + - y (number) vertical origin point from which to rotate + \*/ + matrixproto.rotate = function (a, x, y) { + a = Snap.rad(a); + x = x || 0; + y = y || 0; + var cos = +math.cos(a).toFixed(9), + sin = +math.sin(a).toFixed(9); + this.add(cos, sin, -sin, cos, x, y); + return this.add(1, 0, 0, 1, -x, -y); + }; + /*\ + * Matrix.x + [ method ] + ** + * Returns x coordinate for given point after transformation described by the matrix. See also @Matrix.y + - x (number) + - y (number) + = (number) x + \*/ + matrixproto.x = function (x, y) { + return x * this.a + y * this.c + this.e; + }; + /*\ + * Matrix.y + [ method ] + ** + * Returns y coordinate for given point after transformation described by the matrix. See also @Matrix.x + - x (number) + - y (number) + = (number) y + \*/ + matrixproto.y = function (x, y) { + return x * this.b + y * this.d + this.f; + }; + matrixproto.get = function (i) { + return +this[Str.fromCharCode(97 + i)].toFixed(4); + }; + matrixproto.toString = function () { + return "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")"; + }; + matrixproto.offset = function () { + return [this.e.toFixed(4), this.f.toFixed(4)]; + }; + function norm(a) { + return a[0] * a[0] + a[1] * a[1]; + } + function normalize(a) { + var mag = math.sqrt(norm(a)); + a[0] && (a[0] /= mag); + a[1] && (a[1] /= mag); + } + /*\ + * Matrix.determinant + [ method ] + ** + * Finds determinant of the given matrix. + = (number) determinant + \*/ + matrixproto.determinant = function () { + return this.a * this.d - this.b * this.c; + }; + /*\ + * Matrix.split + [ method ] + ** + * Splits matrix into primitive transformations + = (object) in format: + o dx (number) translation by x + o dy (number) translation by y + o scalex (number) scale by x + o scaley (number) scale by y + o shear (number) shear + o rotate (number) rotation in deg + o isSimple (boolean) could it be represented via simple transformations + \*/ + matrixproto.split = function () { + var out = {}; + // translation + out.dx = this.e; + out.dy = this.f; + + // scale and shear + var row = [[this.a, this.c], [this.b, this.d]]; + out.scalex = math.sqrt(norm(row[0])); + normalize(row[0]); + + out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1]; + row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear]; + + out.scaley = math.sqrt(norm(row[1])); + normalize(row[1]); + out.shear /= out.scaley; + + if (this.determinant() < 0) { + out.scalex = -out.scalex; + } + + // rotation + var sin = -row[0][1], + cos = row[1][1]; + if (cos < 0) { + out.rotate = Snap.deg(math.acos(cos)); + if (sin < 0) { + out.rotate = 360 - out.rotate; + } + } else { + out.rotate = Snap.deg(math.asin(sin)); + } + + out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate); + out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate; + out.noRotation = !+out.shear.toFixed(9) && !out.rotate; + return out; + }; + /*\ + * Matrix.toTransformString + [ method ] + ** + * Returns transform string that represents given matrix + = (string) transform string + \*/ + matrixproto.toTransformString = function (shorter) { + var s = shorter || this.split(); + if (!+s.shear.toFixed(9)) { + s.scalex = +s.scalex.toFixed(4); + s.scaley = +s.scaley.toFixed(4); + s.rotate = +s.rotate.toFixed(4); + return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) + + (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) + + (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E); + } else { + return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)]; + } + }; + })(Matrix.prototype); + /*\ + * Snap.Matrix + [ method ] + ** + * Utility method + ** + * Returns a matrix based on the given parameters + - a (number) + - b (number) + - c (number) + - d (number) + - e (number) + - f (number) + * or + - svgMatrix (SVGMatrix) + = (object) @Matrix + \*/ + Snap.Matrix = Matrix; +}); +// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { + var has = "hasOwnProperty", + make = Snap._.make, + wrap = Snap._.wrap, + is = Snap.is, + getSomeDefs = Snap._.getSomeDefs, + reURLValue = /^url\(#?([^)]+)\)$/, + $ = Snap._.$, + URL = Snap.url, + Str = String, + separator = Snap._.separator, + E = ""; + // Attributes event handlers + eve.on("snap.util.attr.mask", function (value) { + if (value instanceof Element || value instanceof Fragment) { + eve.stop(); + if (value instanceof Fragment && value.node.childNodes.length == 1) { + value = value.node.firstChild; + getSomeDefs(this).appendChild(value); + value = wrap(value); + } + if (value.type == "mask") { + var mask = value; + } else { + mask = make("mask", getSomeDefs(this)); + mask.node.appendChild(value.node); + !mask.node.id && $(mask.node, { + id: mask.id + }); + } + $(this.node, { + mask: URL(mask.id) + }); + } + }); + (function (clipIt) { + eve.on("snap.util.attr.clip", clipIt); + eve.on("snap.util.attr.clip-path", clipIt); + eve.on("snap.util.attr.clipPath", clipIt); + }(function (value) { + if (value instanceof Element || value instanceof Fragment) { + eve.stop(); + if (value.type == "clipPath") { + var clip = value; + } else { + clip = make("clipPath", getSomeDefs(this)); + clip.node.appendChild(value.node); + !clip.node.id && $(clip.node, { + id: clip.id + }); + } + $(this.node, { + "clip-path": URL(clip.id) + }); + } + })); + function fillStroke(name) { + return function (value) { + eve.stop(); + if (value instanceof Fragment && value.node.childNodes.length == 1 && + (value.node.firstChild.tagName == "radialGradient" || + value.node.firstChild.tagName == "linearGradient" || + value.node.firstChild.tagName == "pattern")) { + value = value.node.firstChild; + getSomeDefs(this).appendChild(value); + value = wrap(value); + } + if (value instanceof Element) { + if (value.type == "radialGradient" || value.type == "linearGradient" + || value.type == "pattern") { + if (!value.node.id) { + $(value.node, { + id: value.id + }); + } + var fill = URL(value.node.id); + } else { + fill = value.attr(name); + } + } else { + fill = Snap.color(value); + if (fill.error) { + var grad = gradient(getSomeDefs(this), value); + if (grad) { + if (!grad.node.id) { + $(grad.node, { + id: grad.id + }); + } + fill = URL(grad.node.id); + } else { + fill = value; + } + } else { + fill = Str(fill); + } + } + var attrs = {}; + attrs[name] = fill; + $(this.node, attrs); + this.node.style[name] = E; + }; + } + eve.on("snap.util.attr.fill", fillStroke("fill")); + eve.on("snap.util.attr.stroke", fillStroke("stroke")); + var gradrg = /^([lr])(?:\(([^)]*)\))?(.*)$/i; + eve.on("snap.util.grad.parse", function parseGrad(string) { + string = Str(string); + var tokens = string.match(gradrg); + if (!tokens) { + return null; + } + var type = tokens[1], + params = tokens[2], + stops = tokens[3]; + params = params.split(/\s*,\s*/).map(function (el) { + return +el == el ? +el : el; + }); + if (params.length == 1 && params[0] == 0) { + params = []; + } + stops = stops.split("-"); + stops = stops.map(function (el) { + el = el.split(":"); + var out = { + color: el[0] + }; + if (el[1]) { + out.offset = parseFloat(el[1]); + } + return out; + }); + return { + type: type, + params: params, + stops: stops + }; + }); + + eve.on("snap.util.attr.d", function (value) { + eve.stop(); + if (is(value, "array") && is(value[0], "array")) { + value = Snap.path.toString.call(value); + } + value = Str(value); + if (value.match(/[ruo]/i)) { + value = Snap.path.toAbsolute(value); + } + $(this.node, {d: value}); + })(-1); + eve.on("snap.util.attr.#text", function (value) { + eve.stop(); + value = Str(value); + var txt = glob.doc.createTextNode(value); + while (this.node.firstChild) { + this.node.removeChild(this.node.firstChild); + } + this.node.appendChild(txt); + })(-1); + eve.on("snap.util.attr.path", function (value) { + eve.stop(); + this.attr({d: value}); + })(-1); + eve.on("snap.util.attr.class", function (value) { + eve.stop(); + this.node.className.baseVal = value; + })(-1); + eve.on("snap.util.attr.viewBox", function (value) { + var vb; + if (is(value, "object") && "x" in value) { + vb = [value.x, value.y, value.width, value.height].join(" "); + } else if (is(value, "array")) { + vb = value.join(" "); + } else { + vb = value; + } + $(this.node, { + viewBox: vb + }); + eve.stop(); + })(-1); + eve.on("snap.util.attr.transform", function (value) { + this.transform(value); + eve.stop(); + })(-1); + eve.on("snap.util.attr.r", function (value) { + if (this.type == "rect") { + eve.stop(); + $(this.node, { + rx: value, + ry: value + }); + } + })(-1); + eve.on("snap.util.attr.textpath", function (value) { + eve.stop(); + if (this.type == "text") { + var id, tp, node; + if (!value && this.textPath) { + tp = this.textPath; + while (tp.node.firstChild) { + this.node.appendChild(tp.node.firstChild); + } + tp.remove(); + delete this.textPath; + return; + } + if (is(value, "string")) { + var defs = getSomeDefs(this), + path = wrap(defs.parentNode).path(value); + defs.appendChild(path.node); + id = path.id; + path.attr({id: id}); + } else { + value = wrap(value); + if (value instanceof Element) { + id = value.attr("id"); + if (!id) { + id = value.id; + value.attr({id: id}); + } + } + } + if (id) { + tp = this.textPath; + node = this.node; + if (tp) { + tp.attr({"xlink:href": "#" + id}); + } else { + tp = $("textPath", { + "xlink:href": "#" + id + }); + while (node.firstChild) { + tp.appendChild(node.firstChild); + } + node.appendChild(tp); + this.textPath = wrap(tp); + } + } + } + })(-1); + eve.on("snap.util.attr.text", function (value) { + if (this.type == "text") { + var i = 0, + node = this.node, + tuner = function (chunk) { + var out = $("tspan"); + if (is(chunk, "array")) { + for (var i = 0; i < chunk.length; i++) { + out.appendChild(tuner(chunk[i])); + } + } else { + out.appendChild(glob.doc.createTextNode(chunk)); + } + out.normalize && out.normalize(); + return out; + }; + while (node.firstChild) { + node.removeChild(node.firstChild); + } + var tuned = tuner(value); + while (tuned.firstChild) { + node.appendChild(tuned.firstChild); + } + } + eve.stop(); + })(-1); + eve.on("snap.util.getattr.transform", function () { + eve.stop(); + return this.transform(); + })(-1); + eve.on("snap.util.getattr.textpath", function () { + eve.stop(); + return this.textPath; + })(-1); + // Markers + (function () { + function getter(end) { + return function () { + eve.stop(); + var style = glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue("marker-" + end); + if (style == "none") { + return style; + } else { + return Snap(glob.doc.getElementById(style.match(reURLValue)[1])); + } + }; + } + function setter(end) { + return function (value) { + eve.stop(); + var name = "marker" + end.charAt(0).toUpperCase() + end.substring(1); + if (value == "" || !value) { + this.node.style[name] = "none"; + return; + } + if (value.type == "marker") { + var id = value.node.id; + if (!id) { + $(value.node, {id: value.id}); + } + this.node.style[name] = URL(id); + return; + } + }; + } + eve.on("snap.util.getattr.marker-end", getter("end"))(-1); + eve.on("snap.util.getattr.markerEnd", getter("end"))(-1); + eve.on("snap.util.getattr.marker-start", getter("start"))(-1); + eve.on("snap.util.getattr.markerStart", getter("start"))(-1); + eve.on("snap.util.getattr.marker-mid", getter("mid"))(-1); + eve.on("snap.util.getattr.markerMid", getter("mid"))(-1); + eve.on("snap.util.attr.marker-end", setter("end"))(-1); + eve.on("snap.util.attr.markerEnd", setter("end"))(-1); + eve.on("snap.util.attr.marker-start", setter("start"))(-1); + eve.on("snap.util.attr.markerStart", setter("start"))(-1); + eve.on("snap.util.attr.marker-mid", setter("mid"))(-1); + eve.on("snap.util.attr.markerMid", setter("mid"))(-1); + }()); + eve.on("snap.util.getattr.r", function () { + if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) { + eve.stop(); + return $(this.node, "rx"); + } + })(-1); + function textExtract(node) { + var out = []; + var children = node.childNodes; + for (var i = 0, ii = children.length; i < ii; i++) { + var chi = children[i]; + if (chi.nodeType == 3) { + out.push(chi.nodeValue); + } + if (chi.tagName == "tspan") { + if (chi.childNodes.length == 1 && chi.firstChild.nodeType == 3) { + out.push(chi.firstChild.nodeValue); + } else { + out.push(textExtract(chi)); + } + } + } + return out; + } + eve.on("snap.util.getattr.text", function () { + if (this.type == "text" || this.type == "tspan") { + eve.stop(); + var out = textExtract(this.node); + return out.length == 1 ? out[0] : out; + } + })(-1); + eve.on("snap.util.getattr.#text", function () { + return this.node.textContent; + })(-1); + eve.on("snap.util.getattr.viewBox", function () { + eve.stop(); + var vb = $(this.node, "viewBox"); + if (vb) { + vb = vb.split(separator); + return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]); + } else { + return; + } + })(-1); + eve.on("snap.util.getattr.points", function () { + var p = $(this.node, "points"); + eve.stop(); + return p.split(separator); + }); + eve.on("snap.util.getattr.path", function () { + var p = $(this.node, "d"); + eve.stop(); + return p; + }); + eve.on("snap.util.getattr.class", function () { + return this.node.className.baseVal; + }); + function getFontSize() { + eve.stop(); + return this.node.style.fontSize; + } + eve.on("snap.util.getattr.fontSize", getFontSize)(-1); + eve.on("snap.util.getattr.font-size", getFontSize)(-1); +}); +// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { + var proto = Paper.prototype, + is = Snap.is; + /*\ + * Paper.rect + [ method ] + * + * Draws a rectangle + ** + - x (number) x coordinate of the top left corner + - y (number) y coordinate of the top left corner + - width (number) width + - height (number) height + - rx (number) #optional horizontal radius for rounded corners, default is 0 + - ry (number) #optional vertical radius for rounded corners, default is rx or 0 + = (object) the `rect` element + ** + > Usage + | // regular rectangle + | var c = paper.rect(10, 10, 50, 50); + | // rectangle with rounded corners + | var c = paper.rect(40, 40, 50, 50, 10); + \*/ + proto.rect = function (x, y, w, h, rx, ry) { + var attr; + if (ry == null) { + ry = rx; + } + if (is(x, "object") && x == "[object Object]") { + attr = x; + } else if (x != null) { + attr = { + x: x, + y: y, + width: w, + height: h + }; + if (rx != null) { + attr.rx = rx; + attr.ry = ry; + } + } + return this.el("rect", attr); + }; + /*\ + * Paper.circle + [ method ] + ** + * Draws a circle + ** + - x (number) x coordinate of the centre + - y (number) y coordinate of the centre + - r (number) radius + = (object) the `circle` element + ** + > Usage + | var c = paper.circle(50, 50, 40); + \*/ + proto.circle = function (cx, cy, r) { + var attr; + if (is(cx, "object") && cx == "[object Object]") { + attr = cx; + } else if (cx != null) { + attr = { + cx: cx, + cy: cy, + r: r + }; + } + return this.el("circle", attr); + }; + + var preload = (function () { + function onerror() { + this.parentNode.removeChild(this); + } + return function (src, f) { + var img = glob.doc.createElement("img"), + body = glob.doc.body; + img.style.cssText = "position:absolute;left:-9999em;top:-9999em"; + img.onload = function () { + f.call(img); + img.onload = img.onerror = null; + body.removeChild(img); + }; + img.onerror = onerror; + body.appendChild(img); + img.src = src; + }; + }()); + + /*\ + * Paper.image + [ method ] + ** + * Places an image on the surface + ** + - src (string) URI of the source image + - x (number) x offset position + - y (number) y offset position + - width (number) width of the image + - height (number) height of the image + = (object) the `image` element + * or + = (object) Snap element object with type `image` + ** + > Usage + | var c = paper.image("apple.png", 10, 10, 80, 80); + \*/ + proto.image = function (src, x, y, width, height) { + var el = this.el("image"); + if (is(src, "object") && "src" in src) { + el.attr(src); + } else if (src != null) { + var set = { + "xlink:href": src, + preserveAspectRatio: "none" + }; + if (x != null && y != null) { + set.x = x; + set.y = y; + } + if (width != null && height != null) { + set.width = width; + set.height = height; + } else { + preload(src, function () { + Snap._.$(el.node, { + width: this.offsetWidth, + height: this.offsetHeight + }); + }); + } + Snap._.$(el.node, set); + } + return el; + }; + /*\ + * Paper.ellipse + [ method ] + ** + * Draws an ellipse + ** + - x (number) x coordinate of the centre + - y (number) y coordinate of the centre + - rx (number) horizontal radius + - ry (number) vertical radius + = (object) the `ellipse` element + ** + > Usage + | var c = paper.ellipse(50, 50, 40, 20); + \*/ + proto.ellipse = function (cx, cy, rx, ry) { + var attr; + if (is(cx, "object") && cx == "[object Object]") { + attr = cx; + } else if (cx != null) { + attr ={ + cx: cx, + cy: cy, + rx: rx, + ry: ry + }; + } + return this.el("ellipse", attr); + }; + // SIERRA Paper.path(): Unclear from the link what a Catmull-Rom curveto is, and why it would make life any easier. + /*\ + * Paper.path + [ method ] + ** + * Creates a `` element using the given string as the path's definition + - pathString (string) #optional path string in SVG format + * Path string consists of one-letter commands, followed by comma seprarated arguments in numerical form. Example: + | "M10,20L30,40" + * This example features two commands: `M`, with arguments `(10, 20)` and `L` with arguments `(30, 40)`. Uppercase letter commands express coordinates in absolute terms, while lowercase commands express them in relative terms from the most recently declared coordinates. + * + #

Here is short list of commands available, for more details see SVG path string format or article about path strings at MDN.

+ # + # + # + # + # + # + # + # + # + # + # + #
CommandNameParameters
Mmoveto(x y)+
Zclosepath(none)
Llineto(x y)+
Hhorizontal linetox+
Vvertical linetoy+
Ccurveto(x1 y1 x2 y2 x y)+
Ssmooth curveto(x2 y2 x y)+
Qquadratic Bézier curveto(x1 y1 x y)+
Tsmooth quadratic Bézier curveto(x y)+
Aelliptical arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
RCatmull-Rom curveto*x1 y1 (x y)+
+ * * _Catmull-Rom curveto_ is a not standard SVG command and added to make life easier. + * Note: there is a special case when a path consists of only three commands: `M10,10R…z`. In this case the path connects back to its starting point. + > Usage + | var c = paper.path("M10 10L90 90"); + | // draw a diagonal line: + | // move to 10,10, line to 90,90 + \*/ + proto.path = function (d) { + var attr; + if (is(d, "object") && !is(d, "array")) { + attr = d; + } else if (d) { + attr = {d: d}; + } + return this.el("path", attr); + }; + /*\ + * Paper.g + [ method ] + ** + * Creates a group element + ** + - varargs (…) #optional elements to nest within the group + = (object) the `g` element + ** + > Usage + | var c1 = paper.circle(), + | c2 = paper.rect(), + | g = paper.g(c2, c1); // note that the order of elements is different + * or + | var c1 = paper.circle(), + | c2 = paper.rect(), + | g = paper.g(); + | g.add(c2, c1); + \*/ + /*\ + * Paper.group + [ method ] + ** + * See @Paper.g + \*/ + proto.group = proto.g = function (first) { + var attr, + el = this.el("g"); + if (arguments.length == 1 && first && !first.type) { + el.attr(first); + } else if (arguments.length) { + el.add(Array.prototype.slice.call(arguments, 0)); + } + return el; + }; + /*\ + * Paper.svg + [ method ] + ** + * Creates a nested SVG element. + - x (number) @optional X of the element + - y (number) @optional Y of the element + - width (number) @optional width of the element + - height (number) @optional height of the element + - vbx (number) @optional viewbox X + - vby (number) @optional viewbox Y + - vbw (number) @optional viewbox width + - vbh (number) @optional viewbox height + ** + = (object) the `svg` element + ** + \*/ + proto.svg = function (x, y, width, height, vbx, vby, vbw, vbh) { + var attrs = {}; + if (is(x, "object") && y == null) { + attrs = x; + } else { + if (x != null) { + attrs.x = x; + } + if (y != null) { + attrs.y = y; + } + if (width != null) { + attrs.width = width; + } + if (height != null) { + attrs.height = height; + } + if (vbx != null && vby != null && vbw != null && vbh != null) { + attrs.viewBox = [vbx, vby, vbw, vbh]; + } + } + return this.el("svg", attrs); + }; + /*\ + * Paper.mask + [ method ] + ** + * Equivalent in behaviour to @Paper.g, except it’s a mask. + ** + = (object) the `mask` element + ** + \*/ + proto.mask = function (first) { + var attr, + el = this.el("mask"); + if (arguments.length == 1 && first && !first.type) { + el.attr(first); + } else if (arguments.length) { + el.add(Array.prototype.slice.call(arguments, 0)); + } + return el; + }; + /*\ + * Paper.ptrn + [ method ] + ** + * Equivalent in behaviour to @Paper.g, except it’s a mask. + - x (number) @optional X of the element + - y (number) @optional Y of the element + - width (number) @optional width of the element + - height (number) @optional height of the element + - vbx (number) @optional viewbox X + - vby (number) @optional viewbox Y + - vbw (number) @optional viewbox width + - vbh (number) @optional viewbox height + ** + = (object) the `mask` element + ** + \*/ + proto.ptrn = function (x, y, width, height, vx, vy, vw, vh) { + if (is(x, "object")) { + var attr = x; + } else if (!arguments.length) { + attr = {patternUnits: "userSpaceOnUse"}; + } else { + attr = {}; + if (x != null) { + attr.x = x; + } + if (y != null) { + attr.y = y; + } + if (width != null) { + attr.width = width; + } + if (height != null) { + attr.height = height; + } + if (vbx != null && vby != null && vbw != null && vbh != null) { + attr.viewBox = [vbx, vby, vbw, vbh]; + } + } + return this.el("pattern", attr); + }; + /*\ + * Paper.use + [ method ] + ** + * Creates a element. + - id (string) @optional id of element to link + * or + - id (Element) @optional element to link + ** + = (object) the `use` element + ** + \*/ + proto.use = function (id) { + if (id != null) { + var el = make("use", this.node); + if (id instanceof Element) { + if (!id.attr("id")) { + id.attr({id: ID()}); + } + id = id.attr("id"); + } + return this.el("use", {"xlink:href": id}); + } else { + return Element.prototype.use.call(this); + } + }; + /*\ + * Paper.text + [ method ] + ** + * Draws a text string + ** + - x (number) x coordinate position + - y (number) y coordinate position + - text (string|array) The text string to draw or array of strings to nest within separate `` elements + = (object) the `text` element + ** + > Usage + | var t1 = paper.text(50, 50, "Snap"); + | var t2 = paper.text(50, 50, ["S","n","a","p"]); + | // Text path usage + | t1.attr({textpath: "M10,10L100,100"}); + | // or + | var pth = paper.path("M10,10L100,100"); + | t1.attr({textpath: pth}); + \*/ + proto.text = function (x, y, text) { + var attr = {}; + if (is(x, "object")) { + attr = x; + } else if (x != null) { + attr = { + x: x, + y: y, + text: text || "" + }; + } + return this.el("text", attr); + }; + /*\ + * Paper.line + [ method ] + ** + * Draws a line + ** + - x1 (number) x coordinate position of the start + - y1 (number) y coordinate position of the start + - x2 (number) x coordinate position of the end + - y2 (number) y coordinate position of the end + = (object) the `line` element + ** + > Usage + | var t1 = paper.line(50, 50, 100, 100); + \*/ + proto.line = function (x1, y1, x2, y2) { + var attr = {}; + if (is(x1, "object")) { + attr = x1; + } else if (x1 != null) { + attr = { + x1: x1, + x2: x2, + y1: y1, + y2: y2 + }; + } + return this.el("line", attr); + }; + /*\ + * Paper.polyline + [ method ] + ** + * Draws a polyline + ** + - points (array) array of points + * or + - varargs (…) points + = (object) the `polyline` element + ** + > Usage + | var p1 = paper.polyline([10, 10, 100, 100]); + | var p2 = paper.polyline(10, 10, 100, 100); + \*/ + proto.polyline = function (points) { + if (arguments.length > 1) { + points = Array.prototype.slice.call(arguments, 0); + } + var attr = {}; + if (is(points, "object") && !is(points, "array")) { + attr = points; + } else if (points != null) { + attr = {points: points}; + } + return this.el("polyline", attr); + }; + /*\ + * Paper.polygon + [ method ] + ** + * Draws a polygon. See @Paper.polyline + \*/ + proto.polygon = function (points) { + if (arguments.length > 1) { + points = Array.prototype.slice.call(arguments, 0); + } + var attr = {}; + if (is(points, "object") && !is(points, "array")) { + attr = points; + } else if (points != null) { + attr = {points: points}; + } + return this.el("polygon", attr); + }; + // gradients + (function () { + var $ = Snap._.$; + // gradients' helpers + function Gstops() { + return this.selectAll("stop"); + } + function GaddStop(color, offset) { + var stop = $("stop"), + attr = { + offset: +offset + "%" + }; + color = Snap.color(color); + attr["stop-color"] = color.hex; + if (color.opacity < 1) { + attr["stop-opacity"] = color.opacity; + } + $(stop, attr); + this.node.appendChild(stop); + return this; + } + function GgetBBox() { + if (this.type == "linearGradient") { + var x1 = $(this.node, "x1") || 0, + x2 = $(this.node, "x2") || 1, + y1 = $(this.node, "y1") || 0, + y2 = $(this.node, "y2") || 0; + return Snap._.box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1)); + } else { + var cx = this.node.cx || .5, + cy = this.node.cy || .5, + r = this.node.r || 0; + return Snap._.box(cx - r, cy - r, r * 2, r * 2); + } + } + function arrayFirstValue(arr) { + var res; + for (var i = 0, ii = arr.length; i < ii; i++) { + res = res || arr[i]; + if (res) { + return res; + } + } + } + function gradient(defs, str) { + var grad = arrayFirstValue(eve("snap.util.grad.parse", null, str)), + el; + if (!grad) { + return null; + } + grad.params.unshift(defs); + if (grad.type.toLowerCase() == "l") { + el = gradientLinear.apply(0, grad.params); + } else { + el = gradientRadial.apply(0, grad.params); + } + if (grad.type != grad.type.toLowerCase()) { + $(el.node, { + gradientUnits: "userSpaceOnUse" + }); + } + var stops = grad.stops, + len = stops.length, + start = 0, + j = 0; + function seed(i, end) { + var step = (end - start) / (i - j); + for (var k = j; k < i; k++) { + stops[k].offset = +(+start + step * (k - j)).toFixed(2); + } + j = i; + start = end; + } + len--; + for (var i = 0; i < len; i++) if ("offset" in stops[i]) { + seed(i, stops[i].offset); + } + stops[len].offset = stops[len].offset || 100; + seed(len, stops[len].offset); + for (i = 0; i <= len; i++) { + var stop = stops[i]; + el.addStop(stop.color, stop.offset); + } + return el; + } + function gradientLinear(defs, x1, y1, x2, y2) { + var el = Snap._.make("linearGradient", defs); + el.stops = Gstops; + el.addStop = GaddStop; + el.getBBox = GgetBBox; + if (x1 != null) { + $(el.node, { + x1: x1, + y1: y1, + x2: x2, + y2: y2 + }); + } + return el; + } + function gradientRadial(defs, cx, cy, r, fx, fy) { + var el = Snap._.make("radialGradient", defs); + el.stops = Gstops; + el.addStop = GaddStop; + el.getBBox = GgetBBox; + if (cx != null) { + $(el.node, { + cx: cx, + cy: cy, + r: r + }); + } + if (fx != null && fy != null) { + $(el.node, { + fx: fx, + fy: fy + }); + } + return el; + } + /*\ + * Paper.gradient + [ method ] + ** + * Creates a gradient element + ** + - gradient (string) gradient descriptor + > Gradient Descriptor + * The gradient descriptor is an expression formatted as + * follows: `()`. The `` can be + * either linear or radial. The uppercase `L` or `R` letters + * indicate absolute coordinates offset from the SVG surface. + * Lowercase `l` or `r` letters indicate coordinates + * calculated relative to the element to which the gradient is + * applied. Coordinates specify a linear gradient vector as + * `x1`, `y1`, `x2`, `y2`, or a radial gradient as `cx`, `cy`, + * `r` and optional `fx`, `fy` specifying a focal point away + * from the center of the circle. Specify `` as a list + * of dash-separated CSS color values. Each color may be + * followed by a custom offset value, separated with a colon + * character. + > Examples + * Linear gradient, relative from top-left corner to bottom-right + * corner, from black through red to white: + | var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff"); + * Linear gradient, absolute from (0, 0) to (100, 100), from black + * through red at 25% to white: + | var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff"); + * Radial gradient, relative from the center of the element with radius + * half the width, from black to white: + | var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff"); + * To apply the gradient: + | paper.circle(50, 50, 40).attr({ + | fill: g + | }); + = (object) the `gradient` element + \*/ + proto.gradient = function (str) { + return gradient(this.defs, str); + }; + proto.gradientLinear = function (x1, y1, x2, y2) { + return gradientLinear(this.defs, x1, y1, x2, y2); + }; + proto.gradientRadial = function (cx, cy, r, fx, fy) { + return gradientRadial(this.defs, cx, cy, r, fx, fy); + }; + /*\ + * Paper.toString + [ method ] + ** + * Returns SVG code for the @Paper + = (string) SVG code for the @Paper + \*/ + proto.toString = function () { + var doc = this.node.ownerDocument, + f = doc.createDocumentFragment(), + d = doc.createElement("div"), + svg = this.node.cloneNode(true), + res; + f.appendChild(d); + d.appendChild(svg); + Snap._.$(svg, {xmlns: "http://www.w3.org/2000/svg"}); + res = d.innerHTML; + f.removeChild(f.firstChild); + return res; + }; + /*\ + * Paper.clear + [ method ] + ** + * Removes all child nodes of the paper, except . + \*/ + proto.clear = function () { + var node = this.node.firstChild, + next; + while (node) { + next = node.nextSibling; + if (node.tagName != "defs") { + node.parentNode.removeChild(node); + } else { + proto.clear.call({node: node}); + } + node = next; + } + }; + }()); +}); // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/doc/css/dr.css b/doc/css/dr.css index 169fa17..e85f5a8 100644 --- a/doc/css/dr.css +++ b/doc/css/dr.css @@ -38,6 +38,10 @@ h5:hover a.dr-sourceline { .dr-type { float: left; } +.dr-title { + float: left; + margin: 0 8px 0 0; +} .dr-type em, .dr-returns em, .dr-property em { @@ -137,4 +141,4 @@ ol.dr-json ol.dr-json { list-style: none; margin: 0; padding: 0; -} \ No newline at end of file +} diff --git a/doc/reference.html b/doc/reference.html index 98d2181..074d13a 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -331,138 +331,18 @@ Fragment.selectAll() -
  • - Matrix -
  • - -
  • - Matrix.add() -
  • - -
  • - Matrix.clone() -
  • - -
  • - Matrix.determinant() -
  • - -
  • - Matrix.invert() -
  • - -
  • - Matrix.rotate() -
  • - -
  • - Matrix.scale() -
  • - -
  • - Matrix.split() -
  • - -
  • - Matrix.toTransformString() -
  • - -
  • - Matrix.translate() -
  • - -
  • - Matrix.x() -
  • - -
  • - Matrix.y() -
  • -
  • Paper
  • -
  • - Paper.circle() -
  • - -
  • - Paper.clear() -
  • -
  • Paper.el()
  • -
  • - Paper.ellipse() -
  • -
  • Paper.filter()
  • -
  • - Paper.g() -
  • - -
  • - Paper.gradient() -
  • - -
  • - Paper.group() -
  • - -
  • - Paper.image() -
  • - -
  • - Paper.line() -
  • - -
  • - Paper.mask() -
  • - -
  • - Paper.path() -
  • - -
  • - Paper.polygon() -
  • - -
  • - Paper.polyline() -
  • - -
  • - Paper.ptrn() -
  • - -
  • - Paper.rect() -
  • - -
  • - Paper.svg() -
  • - -
  • - Paper.text() -
  • - -
  • - Paper.toString() -
  • - -
  • - Paper.use() -
  • -
  • Set
  • @@ -495,10 +375,6 @@ Snap() -
  • - Snap.Matrix() -
  • -
  • Snap.ajax()
  • @@ -1004,7 +880,7 @@ paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']
    -

    Snap.rad(deg)

    +

    Snap.rad(deg)

    @@ -1064,7 +940,7 @@ paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']
    -

    Snap.deg(rad)

    +

    Snap.deg(rad)

    @@ -1124,7 +1000,7 @@ paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']
    -

    Snap.angle(x1, y1, x2, y2, [x3], [y3])

    +

    Snap.angle(x1, y1, x2, y2, [x3], [y3])

    @@ -1210,7 +1086,7 @@ paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']
    -

    Snap.is(o, type)

    +

    Snap.is(o, type)

    @@ -1273,7 +1149,7 @@ paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']
    -

    Snap.snapTo(values, value, [tolerance])

    +

    Snap.snapTo(values, value, [tolerance])

    @@ -1333,767 +1209,13 @@ paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width'] - -
    -
    - -
    -
    -

    Matrix.add(…)

    -
    -
    -
    -
    - - - - -

    Adds the given matrix to existing one -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. a - number -
    2. -
    3. b - number -
    4. -
    5. c - number -
    6. -
    7. d - number -
    8. -
    9. e - number -
    10. -
    11. f - number -
    12. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. matrix - object - Matrix
    2. - -
    -
    - - - - - - - -
    -
    -
    - -
    -
    -

    Matrix.invert()

    -
    -
    -
    -
    - - - - -

    Returns an inverted version of the matrix -

    - - - - - - - - - - - - - - -

    - Returns: - - object - - Matrix -

    - - - - -
    -
    -
    - -
    -
    -

    Matrix.clone()

    -
    -
    -
    -
    - - - - -

    Returns a copy of the matrix -

    - - - - - - - - - - - - - - -

    - Returns: - - object - - Matrix -

    - - - - -
    -
    -
    - -
    -
    -

    Matrix.translate(x, y)

    -
    -
    -
    -
    - - - - -

    Translate the matrix -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - horizontal offset distance
    2. -
    3. y - number - vertical offset distance
    4. - -
    -
    - - - - - - - -
    -
    -
    - -
    -
    -

    Matrix.scale(x, [y], [cx], [cy])

    -
    -
    -
    -
    - - - - -

    Scales the matrix -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - amount to be scaled, with 1 resulting in no change
    2. -
    3. y - number - amount to scale along the vertical axis. (Otherwise x applies to both axes.)
    4. -
    5. cx - number - horizontal origin point from which to scale
    6. -
    7. cy - number - vertical origin point from which to scale
    8. - -
    -
    - - - - - - - - -

    Default cx, cy is the middle point of the element. -

    - - - - - - - - -
    -
    -
    - -
    -
    -

    Matrix.rotate(a, x, y)

    -
    -
    -
    -
    - - - - -

    Rotates the matrix -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. a - number - angle of rotation, in degrees
    2. -
    3. x - number - horizontal origin point from which to rotate
    4. -
    5. y - number - vertical origin point from which to rotate
    6. - -
    -
    - - - - - - - -
    -
    -
    - -
    -
    -

    Matrix.x(x, y)

    -
    -
    -
    -
    - - - - -

    Returns x coordinate for given point after transformation described by the matrix. See also Matrix.y -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number -
    2. -
    3. y - number -
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - x -

    - - - - -
    -
    -
    - -
    -
    -

    Matrix.y(x, y)

    -
    -
    -
    -
    - - - - -

    Returns y coordinate for given point after transformation described by the matrix. See also Matrix.x -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number -
    2. -
    3. y - number -
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - y -

    - - - - -
    -
    -
    - -
    -
    -

    Matrix.determinant()

    -
    -
    -
    -
    - - - - -

    Finds determinant of the given matrix. -

    - - - - - - - - - - - - - - -

    - Returns: - - number - - determinant -

    - - - - -
    -
    -
    - -
    -
    -

    Matrix.split()

    -
    -
    -
    -
    - - - - -

    Splits matrix into primitive transformations -

    - - - - - - - - - - - - - - -

    - Returns: - - object - - in format: -

    - - - - - - - - - - - -
      - - -
    1. - dx - number - translation by x -
    2. - - - -
    3. - dy - number - translation by y -
    4. - - - -
    5. - scalex - number - scale by x -
    6. - - - -
    7. - scaley - number - scale by y -
    8. - - - -
    9. - shear - number - shear -
    10. - - - -
    11. - rotate - number - rotation in deg -
    12. - - - -
    13. - isSimple - boolean - could it be represented via simple transformations -
    14. - - -
    - - -
    -
    -
    - -
    -
    -

    Matrix.toTransformString()

    -
    -
    -
    -
    - - - - -

    Returns transform string that represents given matrix -

    - - - - - - - - - - - - - - -

    - Returns: - - string - - transform string -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.Matrix(…)

    -
    -
    -
    -
    - - - - -

    Utility method -Returns a matrix based on the given parameters -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. a - number -
    2. -
    3. b - number -
    4. -
    5. c - number -
    6. -
    7. d - number -
    8. -
    9. e - number -
    10. -
    11. f - number -
    12. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. svgMatrix - SVGMatrix -
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Matrix -

    - - - -
    -

    Snap.getRGB(color)

    +

    Snap.getRGB(color)

    @@ -2428,7 +1550,7 @@ Returns a matrix based on the given parameters
    -

    Snap.hsb(h, s, b)

    +

    Snap.hsb(h, s, b)

    @@ -2494,7 +1616,7 @@ Returns a matrix based on the given parameters
    -

    Snap.hsl(h, s, l)

    +

    Snap.hsl(h, s, l)

    @@ -2560,7 +1682,7 @@ Returns a matrix based on the given parameters
    -

    Snap.rgb(r, g, b)

    +

    Snap.rgb(r, g, b)

    @@ -2626,7 +1748,7 @@ Returns a matrix based on the given parameters
    -

    Snap.color(clr)

    +

    Snap.color(clr)

    @@ -2778,7 +1900,7 @@ Returns a matrix based on the given parameters
    -

    Snap.hsb2rgb(h, s, v)

    +

    Snap.hsb2rgb(h, s, v)

    @@ -2896,7 +2018,7 @@ Returns a matrix based on the given parameters
    -

    Snap.hsl2rgb(h, s, l)

    +

    Snap.hsl2rgb(h, s, l)

    @@ -3014,7 +2136,7 @@ Returns a matrix based on the given parameters
    -

    Snap.rgb2hsb(r, g, b)

    +

    Snap.rgb2hsb(r, g, b)

    @@ -3124,7 +2246,7 @@ Returns a matrix based on the given parameters
    -

    Snap.rgb2hsl(r, g, b)

    +

    Snap.rgb2hsl(r, g, b)

    @@ -3234,7 +2356,7 @@ Returns a matrix based on the given parameters
    -

    Snap.parsePathString(pathString)

    +

    Snap.parsePathString(pathString)

    @@ -3295,7 +2417,7 @@ Parses given path string into an array of arrays of path segments
    -

    Snap.parseTransformString(TString)

    +

    Snap.parseTransformString(TString)

    @@ -3356,7 +2478,7 @@ Parses given transform string into an array of transformations
    -

    Snap.select(query)

    +

    Snap.select(query)

    @@ -3416,7 +2538,7 @@ Parses given transform string into an array of transformations
    -

    Snap.selectAll(query)

    +

    Snap.selectAll(query)

    @@ -3476,7 +2598,7 @@ Parses given transform string into an array of transformations
    -

    Element.node(x, y, width, height, refX, refY)

    +

    Element.node(x, y, width, height, refX, refY)

    @@ -3527,7 +2649,7 @@ c.node.onclick = function () {
    -

    Element.type(tstr)

    +

    Element.type(tstr)

    @@ -3552,7 +2674,7 @@ c.node.onclick = function () {
    -

    Element.attr(…)

    +

    Element.attr(…)

    @@ -3697,7 +2819,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.getBBox()

    +

    Element.getBBox()

    @@ -3879,7 +3001,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.transform(tstr)

    +

    Element.transform(tstr)

    @@ -4043,7 +3165,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.parent()

    +

    Element.parent()

    @@ -4085,7 +3207,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.append(el)

    +

    Element.append(el)

    @@ -4145,7 +3267,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.add()

    +

    Element.add()

    @@ -4170,7 +3292,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.appendTo(el)

    +

    Element.appendTo(el)

    @@ -4230,7 +3352,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.prepend(el)

    +

    Element.prepend(el)

    @@ -4290,7 +3412,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.prependTo(el)

    +

    Element.prependTo(el)

    @@ -4350,7 +3472,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.before(el)

    +

    Element.before(el)

    @@ -4410,7 +3532,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.after(el)

    +

    Element.after(el)

    @@ -4470,7 +3592,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.insertBefore(el)

    +

    Element.insertBefore(el)

    @@ -4530,7 +3652,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.insertAfter(el)

    +

    Element.insertAfter(el)

    @@ -4590,7 +3712,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.remove()

    +

    Element.remove()

    @@ -4632,7 +3754,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.select(query)

    +

    Element.select(query)

    @@ -4692,7 +3814,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.selectAll(query)

    +

    Element.selectAll(query)

    @@ -4754,7 +3876,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.asPX(attr, [value])

    +

    Element.asPX(attr, [value])

    @@ -4817,7 +3939,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.use()

    +

    Element.use()

    @@ -4859,7 +3981,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.clone()

    +

    Element.clone()

    @@ -4901,7 +4023,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.toDefs()

    +

    Element.toDefs()

    @@ -4943,7 +4065,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.pattern()

    +

    Element.pattern()

    @@ -4968,7 +4090,7 @@ console.log(el.attr("fill")); // #fc0
    -

    Element.toPattern(x, y, width, height)

    +

    Element.toPattern(x, y, width, height)

    @@ -5068,7 +4190,7 @@ c.attr({
    -

    Element.marker(x, y, width, height, refX, refY)

    +

    Element.marker(x, y, width, height, refX, refY)

    @@ -5155,7 +4277,7 @@ To create a marker you have to specify the bounding rect and reference point:
    -

    Snap.animation(attr, duration, [easing], [callback])

    +

    Snap.animation(attr, duration, [easing], [callback])

    @@ -5224,7 +4346,7 @@ To create a marker you have to specify the bounding rect and reference point:
    -

    Element.inAnim()

    +

    Element.inAnim()

    @@ -5326,7 +4448,7 @@ To create a marker you have to specify the bounding rect and reference point:
    -

    Snap.animate(from, to, setter, duration, [easing], [callback])

    +

    Snap.animate(from, to, setter, duration, [easing], [callback])

    @@ -5487,7 +4609,7 @@ rect.animate({x: 10}, 1000);
    -

    Element.stop()

    +

    Element.stop()

    @@ -5529,7 +4651,7 @@ rect.animate({x: 10}, 1000);
    -

    Element.animate(attrs, duration, [easing], [callback])

    +

    Element.animate(attrs, duration, [easing], [callback])

    @@ -5598,7 +4720,7 @@ rect.animate({x: 10}, 1000);
    -

    Element.data(key, [value])

    +

    Element.data(key, [value])

    @@ -5720,7 +4842,7 @@ with data- attributes)
    -

    Element.removeData([key])

    +

    Element.removeData([key])

    @@ -5781,7 +4903,7 @@ If key is not provided, removes all the data of the element.
    -

    Element.outerSVG()

    +

    Element.outerSVG()

    @@ -5822,12 +4944,12 @@ If key is not provided, removes all the data of the element.
    -
    +
    -

    undefined

    +

    Element.toString()

    -
    +
    @@ -5849,7 +4971,7 @@ If key is not provided, removes all the data of the element.
    -

    Element.innerSVG()

    +

    Element.innerSVG()

    @@ -5891,7 +5013,7 @@ If key is not provided, removes all the data of the element.
    -

    Snap.parse(svg)

    +

    Snap.parse(svg)

    @@ -5951,7 +5073,7 @@ If key is not provided, removes all the data of the element.
    -

    Fragment.select()

    +

    Fragment.select()

    @@ -5976,7 +5098,7 @@ If key is not provided, removes all the data of the element.
    -

    Fragment.selectAll()

    +

    Fragment.selectAll()

    @@ -6001,7 +5123,7 @@ If key is not provided, removes all the data of the element.
    -

    Snap.fragment(varargs)

    +

    Snap.fragment(varargs)

    @@ -6061,7 +5183,7 @@ If key is not provided, removes all the data of the element.
    -

    Paper.el(name, attr)

    +

    Paper.el(name, attr)

    @@ -6151,1696 +5273,13 @@ var c = paper.el("circle", { -
    -
    -
    - -
    -
    -

    Paper.rect(x, y, width, height, [rx], [ry])

    -
    -
    -
    -
    - - - - -

    Draws a rectangle -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - x coordinate of the top left corner
    2. -
    3. y - number - y coordinate of the top left corner
    4. -
    5. width - number - width
    6. -
    7. height - number - height
    8. -
    9. rx - number - horizontal radius for rounded corners, default is 0
    10. -
    11. ry - number - vertical radius for rounded corners, default is rx or 0
    12. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the rect element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    // regular rectangle
    -var c = paper.rect(10, 10, 50, 50);
    -// rectangle with rounded corners
    -var c = paper.rect(40, 40, 50, 50, 10);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.circle(x, y, r)

    -
    -
    -
    -
    - - - - -

    Draws a circle -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - x coordinate of the centre
    2. -
    3. y - number - y coordinate of the centre
    4. -
    5. r - number - radius
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the circle element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var c = paper.circle(50, 50, 40);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.image(src, x, y, width, height)

    -
    -
    -
    -
    - - - - -

    Places an image on the surface -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. src - string - URI of the source image
    2. -
    3. x - number - x offset position
    4. -
    5. y - number - y offset position
    6. -
    7. width - number - width of the image
    8. -
    9. height - number - height of the image
    10. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the image element -

    - - - - - -

    or -

    - - - - - - - - - - - - - - -

    - Returns: - - object - - Snap element object with type image -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var c = paper.image("apple.png", 10, 10, 80, 80);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.ellipse(x, y, rx, ry)

    -
    -
    -
    -
    - - - - -

    Draws an ellipse -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - x coordinate of the centre
    2. -
    3. y - number - y coordinate of the centre
    4. -
    5. rx - number - horizontal radius
    6. -
    7. ry - number - vertical radius
    8. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the ellipse element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var c = paper.ellipse(50, 50, 40, 20);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.path([pathString])

    -
    -
    -
    -
    - - - - -

    Creates a <path> element using the given string as the path's definition -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. pathString - string - path string in SVG format
    2. - -
    -
    - - - - - - - - -

    Path string consists of one-letter commands, followed by comma seprarated arguments in numerical form. Example: -

    - - - - - - - - - - - - - -
    "M10,20L30,40"
    - - - - - - -

    This example features two commands: M, with arguments (10, 20) and L with arguments (30, 40). Uppercase letter commands express coordinates in absolute terms, while lowercase commands express them in relative terms from the most recently declared coordinates. -

    - - - - - - - - - - - -

    Here is short list of commands available, for more details see SVG path string format or article about path strings at MDN.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    CommandNameParameters
    Mmoveto(x y)+
    Zclosepath(none)
    Llineto(x y)+
    Hhorizontal linetox+
    Vvertical linetoy+
    Ccurveto(x1 y1 x2 y2 x y)+
    Ssmooth curveto(x2 y2 x y)+
    Qquadratic Bézier curveto(x1 y1 x y)+
    Tsmooth quadratic Bézier curveto(x y)+
    Aelliptical arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
    RCatmull-Rom curveto*x1 y1 (x y)+
    - - - - - - - - - -

  • Catmull-Rom curveto is a not standard SVG command and added to make life easier.
  • -Note: there is a special case when a path consists of only three commands: M10,10R…z. In this case the path connects back to its starting point. -

    - - - - - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var c = paper.path("M10 10L90 90");
    -// draw a diagonal line:
    -// move to 10,10, line to 90,90
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.g([varargs])

    -
    -
    -
    -
    - - - - -

    Creates a group element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. varargs - - elements to nest within the group
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the g element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var c1 = paper.circle(),
    -    c2 = paper.rect(),
    -    g = paper.g(c2, c1); // note that the order of elements is different
    - - - - - - -

    or -

    - - - - - - - - - - - - - -
    var c1 = paper.circle(),
    -    c2 = paper.rect(),
    -    g = paper.g();
    -g.add(c2, c1);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.group()

    -
    -
    -
    -
    - - - - -

    See Paper.g -

    - - - - - - - - -
    -
    -
    - -
    -
    -

    Paper.svg(x, y, width, height, vbx, vby, vbw, vbh)

    -
    -
    -
    -
    - - - - -

    Creates a nested SVG element. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - optional X of the element
    2. -
    3. y - number - optional Y of the element
    4. -
    5. width - number - optional width of the element
    6. -
    7. height - number - optional height of the element
    8. -
    9. vbx - number - optional viewbox X
    10. -
    11. vby - number - optional viewbox Y
    12. -
    13. vbw - number - optional viewbox width
    14. -
    15. vbh - number - optional viewbox height
    16. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the svg element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.mask()

    -
    -
    -
    -
    - - - - -

    Equivalent in behaviour to Paper.g, except it’s a mask. -

    - - - - - - - - - - - - - - -

    - Returns: - - object - - the mask element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.ptrn(x, y, width, height, vbx, vby, vbw, vbh)

    -
    -
    -
    -
    - - - - -

    Equivalent in behaviour to Paper.g, except it’s a mask. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - optional X of the element
    2. -
    3. y - number - optional Y of the element
    4. -
    5. width - number - optional width of the element
    6. -
    7. height - number - optional height of the element
    8. -
    9. vbx - number - optional viewbox X
    10. -
    11. vby - number - optional viewbox Y
    12. -
    13. vbw - number - optional viewbox width
    14. -
    15. vbh - number - optional viewbox height
    16. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the mask element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.use(…)

    -
    -
    -
    -
    - - - - -

    Creates a <use> element. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. id - string - optional id of element to link
    2. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. id - Element - optional element to link
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the use element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.text(x, y, text)

    -
    -
    -
    -
    - - - - -

    Draws a text string -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - x coordinate position
    2. -
    3. y - number - y coordinate position
    4. -
    5. text - string array - The text string to draw or array of strings to nest within separate <tspan> elements
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the text element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var t1 = paper.text(50, 50, "Snap");
    -var t2 = paper.text(50, 50, ["S","n","a","p"]);
    -// Text path usage
    -t1.attr({textpath: "M10,10L100,100"});
    -// or
    -var pth = paper.path("M10,10L100,100");
    -t1.attr({textpath: pth});
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.line(x1, y1, x2, y2)

    -
    -
    -
    -
    - - - - -

    Draws a line -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x1 - number - x coordinate position of the start
    2. -
    3. y1 - number - y coordinate position of the start
    4. -
    5. x2 - number - x coordinate position of the end
    6. -
    7. y2 - number - y coordinate position of the end
    8. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the line element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var t1 = paper.line(50, 50, 100, 100);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.polyline(…)

    -
    -
    -
    -
    - - - - -

    Draws a polyline -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. points - array - array of points
    2. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. varargs - - points
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the polyline element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var p1 = paper.polyline([10, 10, 100, 100]);
    -var p2 = paper.polyline(10, 10, 100, 100);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.polygon()

    -
    -
    -
    -
    - - - - -

    Draws a polygon. See Paper.polyline -

    - - - - - - - - -
    -
    -
    - -
    -
    -

    Paper.gradient(gradient)

    -
    -
    -
    -
    - - - - -

    Creates a gradient element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. gradient - string - gradient descriptor
    2. - -
    -
    - - - - - - - - - - - -

    Gradient Descriptor

    - - - - - - - -

    The gradient descriptor is an expression formatted as -follows: <type>(<coords>)<colors>. The <type> can be -either linear or radial. The uppercase L or R letters -indicate absolute coordinates offset from the SVG surface. -Lowercase l or r letters indicate coordinates -calculated relative to the element to which the gradient is -applied. Coordinates specify a linear gradient vector as -x1, y1, x2, y2, or a radial gradient as cx, cy, -r and optional fx, fy specifying a focal point away -from the center of the circle. Specify <colors> as a list -of dash-separated CSS color values. Each color may be -followed by a custom offset value, separated with a colon -character. -

    - - - - - - - - - - - - -

    Examples

    - - - - - - - -

    Linear gradient, relative from top-left corner to bottom-right -corner, from black through red to white: -

    - - - - - - - - - - - - - -
    var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff");
    - - - - - - -

    Linear gradient, absolute from (0, 0) to (100, 100), from black -through red at 25% to white: -

    - - - - - - - - - - - - - -
    var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff");
    - - - - - - -

    Radial gradient, relative from the center of the element with radius -half the width, from black to white: -

    - - - - - - - - - - - - - -
    var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff");
    - - - - - - -

    To apply the gradient: -

    - - - - - - - - - - - - - -
    paper.circle(50, 50, 40).attr({
    -    fill: g
    -});
    - - - - - - - - - - - -

    - Returns: - - object - - the gradient element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.toString()

    -
    -
    -
    -
    - - - - -

    Returns SVG code for the Paper -

    - - - - - - - - - - - - - - -

    - Returns: - - string - - SVG code for the Paper -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.clear()

    -
    -
    -
    -
    - - - - -

    Removes all child nodes of the paper, except <defs>. -

    - - - - - - - -
    -

    Snap.ajax(…)

    +

    Snap.ajax(…)

    @@ -7944,7 +5383,7 @@ half the width, from black to white:
    -

    Snap.load(url, callback, [scope])

    +

    Snap.load(url, callback, [scope])

    @@ -7993,7 +5432,7 @@ half the width, from black to white:
    -

    Snap.getElementByPoint(x, y)

    +

    Snap.getElementByPoint(x, y)

    @@ -8078,7 +5517,7 @@ half the width, from black to white:
    -

    Snap.plugin(f)

    +

    Snap.plugin(f)

    @@ -8102,7 +5541,7 @@ half the width, from black to white: -
    Snap.plugin(function (Snap, Element, Paper, global) {
    +                                  
    Snap.plugin(function (Snap, Element, Paper, global, Fragment) {
         Snap.newmethod = function () {};
         Element.prototype.newmethod = function () {};
         Paper.prototype.newmethod = function () {};
    diff --git a/src/attr.js b/src/attr.js
    new file mode 100644
    index 0000000..1e7adcd
    --- /dev/null
    +++ b/src/attr.js
    @@ -0,0 +1,396 @@
    +// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
    +// 
    +// Licensed under the Apache License, Version 2.0 (the "License");
    +// you may not use this file except in compliance with the License.
    +// You may obtain a copy of the License at
    +// 
    +// http://www.apache.org/licenses/LICENSE-2.0
    +// 
    +// Unless required by applicable law or agreed to in writing, software
    +// distributed under the License is distributed on an "AS IS" BASIS,
    +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +// See the License for the specific language governing permissions and
    +// limitations under the License.
    +Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
    +    var has = "hasOwnProperty",
    +        make = Snap._.make,
    +        wrap = Snap._.wrap,
    +        is = Snap.is,
    +        getSomeDefs = Snap._.getSomeDefs,
    +        reURLValue = /^url\(#?([^)]+)\)$/,
    +        $ = Snap._.$,
    +        URL = Snap.url,
    +        Str = String,
    +        separator = Snap._.separator,
    +        E = "";
    +    // Attributes event handlers
    +    eve.on("snap.util.attr.mask", function (value) {
    +        if (value instanceof Element || value instanceof Fragment) {
    +            eve.stop();
    +            if (value instanceof Fragment && value.node.childNodes.length == 1) {
    +                value = value.node.firstChild;
    +                getSomeDefs(this).appendChild(value);
    +                value = wrap(value);
    +            }
    +            if (value.type == "mask") {
    +                var mask = value;
    +            } else {
    +                mask = make("mask", getSomeDefs(this));
    +                mask.node.appendChild(value.node);
    +                !mask.node.id && $(mask.node, {
    +                    id: mask.id
    +                });
    +            }
    +            $(this.node, {
    +                mask: URL(mask.id)
    +            });
    +        }
    +    });
    +    (function (clipIt) {
    +        eve.on("snap.util.attr.clip", clipIt);
    +        eve.on("snap.util.attr.clip-path", clipIt);
    +        eve.on("snap.util.attr.clipPath", clipIt);
    +    }(function (value) {
    +        if (value instanceof Element || value instanceof Fragment) {
    +            eve.stop();
    +            if (value.type == "clipPath") {
    +                var clip = value;
    +            } else {
    +                clip = make("clipPath", getSomeDefs(this));
    +                clip.node.appendChild(value.node);
    +                !clip.node.id && $(clip.node, {
    +                    id: clip.id
    +                });
    +            }
    +            $(this.node, {
    +                "clip-path": URL(clip.id)
    +            });
    +        }
    +    }));
    +    function fillStroke(name) {
    +        return function (value) {
    +            eve.stop();
    +            if (value instanceof Fragment && value.node.childNodes.length == 1 &&
    +                (value.node.firstChild.tagName == "radialGradient" ||
    +                value.node.firstChild.tagName == "linearGradient" ||
    +                value.node.firstChild.tagName == "pattern")) {
    +                value = value.node.firstChild;
    +                getSomeDefs(this).appendChild(value);
    +                value = wrap(value);
    +            }
    +            if (value instanceof Element) {
    +                if (value.type == "radialGradient" || value.type == "linearGradient"
    +                   || value.type == "pattern") {
    +                    if (!value.node.id) {
    +                        $(value.node, {
    +                            id: value.id
    +                        });
    +                    }
    +                    var fill = URL(value.node.id);
    +                } else {
    +                    fill = value.attr(name);
    +                }
    +            } else {
    +                fill = Snap.color(value);
    +                if (fill.error) {
    +                    var grad = gradient(getSomeDefs(this), value);
    +                    if (grad) {
    +                        if (!grad.node.id) {
    +                            $(grad.node, {
    +                                id: grad.id
    +                            });
    +                        }
    +                        fill = URL(grad.node.id);
    +                    } else {
    +                        fill = value;
    +                    }
    +                } else {
    +                    fill = Str(fill);
    +                }
    +            }
    +            var attrs = {};
    +            attrs[name] = fill;
    +            $(this.node, attrs);
    +            this.node.style[name] = E;
    +        };
    +    }
    +    eve.on("snap.util.attr.fill", fillStroke("fill"));
    +    eve.on("snap.util.attr.stroke", fillStroke("stroke"));
    +    var gradrg = /^([lr])(?:\(([^)]*)\))?(.*)$/i;
    +    eve.on("snap.util.grad.parse", function parseGrad(string) {
    +        string = Str(string);
    +        var tokens = string.match(gradrg);
    +        if (!tokens) {
    +            return null;
    +        }
    +        var type = tokens[1],
    +            params = tokens[2],
    +            stops = tokens[3];
    +        params = params.split(/\s*,\s*/).map(function (el) {
    +            return +el == el ? +el : el;
    +        });
    +        if (params.length == 1 && params[0] == 0) {
    +            params = [];
    +        }
    +        stops = stops.split("-");
    +        stops = stops.map(function (el) {
    +            el = el.split(":");
    +            var out = {
    +                color: el[0]
    +            };
    +            if (el[1]) {
    +                out.offset = parseFloat(el[1]);
    +            }
    +            return out;
    +        });
    +        return {
    +            type: type,
    +            params: params,
    +            stops: stops
    +        };
    +    });
    +
    +    eve.on("snap.util.attr.d", function (value) {
    +        eve.stop();
    +        if (is(value, "array") && is(value[0], "array")) {
    +            value = Snap.path.toString.call(value);
    +        }
    +        value = Str(value);
    +        if (value.match(/[ruo]/i)) {
    +            value = Snap.path.toAbsolute(value);
    +        }
    +        $(this.node, {d: value});
    +    })(-1);
    +    eve.on("snap.util.attr.#text", function (value) {
    +        eve.stop();
    +        value = Str(value);
    +        var txt = glob.doc.createTextNode(value);
    +        while (this.node.firstChild) {
    +            this.node.removeChild(this.node.firstChild);
    +        }
    +        this.node.appendChild(txt);
    +    })(-1);
    +    eve.on("snap.util.attr.path", function (value) {
    +        eve.stop();
    +        this.attr({d: value});
    +    })(-1);
    +    eve.on("snap.util.attr.class", function (value) {
    +        eve.stop();
    +        this.node.className.baseVal = value;
    +    })(-1);
    +    eve.on("snap.util.attr.viewBox", function (value) {
    +        var vb;
    +        if (is(value, "object") && "x" in value) {
    +            vb = [value.x, value.y, value.width, value.height].join(" ");
    +        } else if (is(value, "array")) {
    +            vb = value.join(" ");
    +        } else {
    +            vb = value;
    +        }
    +        $(this.node, {
    +            viewBox: vb
    +        });
    +        eve.stop();
    +    })(-1);
    +    eve.on("snap.util.attr.transform", function (value) {
    +        this.transform(value);
    +        eve.stop();
    +    })(-1);
    +    eve.on("snap.util.attr.r", function (value) {
    +        if (this.type == "rect") {
    +            eve.stop();
    +            $(this.node, {
    +                rx: value,
    +                ry: value
    +            });
    +        }
    +    })(-1);
    +    eve.on("snap.util.attr.textpath", function (value) {
    +        eve.stop();
    +        if (this.type == "text") {
    +            var id, tp, node;
    +            if (!value && this.textPath) {
    +                tp = this.textPath;
    +                while (tp.node.firstChild) {
    +                    this.node.appendChild(tp.node.firstChild);
    +                }
    +                tp.remove();
    +                delete this.textPath;
    +                return;
    +            }
    +            if (is(value, "string")) {
    +                var defs = getSomeDefs(this),
    +                    path = wrap(defs.parentNode).path(value);
    +                defs.appendChild(path.node);
    +                id = path.id;
    +                path.attr({id: id});
    +            } else {
    +                value = wrap(value);
    +                if (value instanceof Element) {
    +                    id = value.attr("id");
    +                    if (!id) {
    +                        id = value.id;
    +                        value.attr({id: id});
    +                    }
    +                }
    +            }
    +            if (id) {
    +                tp = this.textPath;
    +                node = this.node;
    +                if (tp) {
    +                    tp.attr({"xlink:href": "#" + id});
    +                } else {
    +                    tp = $("textPath", {
    +                        "xlink:href": "#" + id
    +                    });
    +                    while (node.firstChild) {
    +                        tp.appendChild(node.firstChild);
    +                    }
    +                    node.appendChild(tp);
    +                    this.textPath = wrap(tp);
    +                }
    +            }
    +        }
    +    })(-1);
    +    eve.on("snap.util.attr.text", function (value) {
    +        if (this.type == "text") {
    +            var i = 0,
    +                node = this.node,
    +                tuner = function (chunk) {
    +                    var out = $("tspan");
    +                    if (is(chunk, "array")) {
    +                        for (var i = 0; i < chunk.length; i++) {
    +                            out.appendChild(tuner(chunk[i]));
    +                        }
    +                    } else {
    +                        out.appendChild(glob.doc.createTextNode(chunk));
    +                    }
    +                    out.normalize && out.normalize();
    +                    return out;
    +                };
    +            while (node.firstChild) {
    +                node.removeChild(node.firstChild);
    +            }
    +            var tuned = tuner(value);
    +            while (tuned.firstChild) {
    +                node.appendChild(tuned.firstChild);
    +            }
    +        }
    +        eve.stop();
    +    })(-1);
    +    eve.on("snap.util.getattr.transform", function () {
    +        eve.stop();
    +        return this.transform();
    +    })(-1);
    +    eve.on("snap.util.getattr.textpath", function () {
    +        eve.stop();
    +        return this.textPath;
    +    })(-1);
    +    // Markers
    +    (function () {
    +        function getter(end) {
    +            return function () {
    +                eve.stop();
    +                var style = glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue("marker-" + end);
    +                if (style == "none") {
    +                    return style;
    +                } else {
    +                    return Snap(glob.doc.getElementById(style.match(reURLValue)[1]));
    +                }
    +            };
    +        }
    +        function setter(end) {
    +            return function (value) {
    +                eve.stop();
    +                var name = "marker" + end.charAt(0).toUpperCase() + end.substring(1);
    +                if (value == "" || !value) {
    +                    this.node.style[name] = "none";
    +                    return;
    +                }
    +                if (value.type == "marker") {
    +                    var id = value.node.id;
    +                    if (!id) {
    +                        $(value.node, {id: value.id});
    +                    }
    +                    this.node.style[name] = URL(id);
    +                    return;
    +                }
    +            };
    +        }
    +        eve.on("snap.util.getattr.marker-end", getter("end"))(-1);
    +        eve.on("snap.util.getattr.markerEnd", getter("end"))(-1);
    +        eve.on("snap.util.getattr.marker-start", getter("start"))(-1);
    +        eve.on("snap.util.getattr.markerStart", getter("start"))(-1);
    +        eve.on("snap.util.getattr.marker-mid", getter("mid"))(-1);
    +        eve.on("snap.util.getattr.markerMid", getter("mid"))(-1);
    +        eve.on("snap.util.attr.marker-end", setter("end"))(-1);
    +        eve.on("snap.util.attr.markerEnd", setter("end"))(-1);
    +        eve.on("snap.util.attr.marker-start", setter("start"))(-1);
    +        eve.on("snap.util.attr.markerStart", setter("start"))(-1);
    +        eve.on("snap.util.attr.marker-mid", setter("mid"))(-1);
    +        eve.on("snap.util.attr.markerMid", setter("mid"))(-1);
    +    }());
    +    eve.on("snap.util.getattr.r", function () {
    +        if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) {
    +            eve.stop();
    +            return $(this.node, "rx");
    +        }
    +    })(-1);
    +    function textExtract(node) {
    +        var out = [];
    +        var children = node.childNodes;
    +        for (var i = 0, ii = children.length; i < ii; i++) {
    +            var chi = children[i];
    +            if (chi.nodeType == 3) {
    +                out.push(chi.nodeValue);
    +            }
    +            if (chi.tagName == "tspan") {
    +                if (chi.childNodes.length == 1 && chi.firstChild.nodeType == 3) {
    +                    out.push(chi.firstChild.nodeValue);
    +                } else {
    +                    out.push(textExtract(chi));
    +                }
    +            }
    +        }
    +        return out;
    +    }
    +    eve.on("snap.util.getattr.text", function () {
    +        if (this.type == "text" || this.type == "tspan") {
    +            eve.stop();
    +            var out = textExtract(this.node);
    +            return out.length == 1 ? out[0] : out;
    +        }
    +    })(-1);
    +    eve.on("snap.util.getattr.#text", function () {
    +        return this.node.textContent;
    +    })(-1);
    +    eve.on("snap.util.getattr.viewBox", function () {
    +        eve.stop();
    +        var vb = $(this.node, "viewBox");
    +        if (vb) {
    +            vb = vb.split(separator);
    +            return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]);
    +        } else {
    +            return;
    +        }
    +    })(-1);
    +    eve.on("snap.util.getattr.points", function () {
    +        var p = $(this.node, "points");
    +        eve.stop();
    +        return p.split(separator);
    +    });
    +    eve.on("snap.util.getattr.path", function () {
    +        var p = $(this.node, "d");
    +        eve.stop();
    +        return p;
    +    });
    +    eve.on("snap.util.getattr.class", function () {
    +        return this.node.className.baseVal;
    +    });
    +    function getFontSize() {
    +        eve.stop();
    +        return this.node.style.fontSize;
    +    }
    +    eve.on("snap.util.getattr.fontSize", getFontSize)(-1);
    +    eve.on("snap.util.getattr.font-size", getFontSize)(-1);
    +});
    \ No newline at end of file
    diff --git a/src/matrix.js b/src/matrix.js
    new file mode 100644
    index 0000000..614d4f2
    --- /dev/null
    +++ b/src/matrix.js
    @@ -0,0 +1,299 @@
    +// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
    +// 
    +// Licensed under the Apache License, Version 2.0 (the "License");
    +// you may not use this file except in compliance with the License.
    +// You may obtain a copy of the License at
    +// 
    +// http://www.apache.org/licenses/LICENSE-2.0
    +// 
    +// Unless required by applicable law or agreed to in writing, software
    +// distributed under the License is distributed on an "AS IS" BASIS,
    +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +// See the License for the specific language governing permissions and
    +// limitations under the License.
    +Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
    +    var objectToString = Object.prototype.toString,
    +        Str = String,
    +        math = Math,
    +        E = "";
    +    function Matrix(a, b, c, d, e, f) {
    +        if (b == null && objectToString.call(a) == "[object SVGMatrix]") {
    +            this.a = a.a;
    +            this.b = a.b;
    +            this.c = a.c;
    +            this.d = a.d;
    +            this.e = a.e;
    +            this.f = a.f;
    +            return;
    +        }
    +        if (a != null) {
    +            this.a = +a;
    +            this.b = +b;
    +            this.c = +c;
    +            this.d = +d;
    +            this.e = +e;
    +            this.f = +f;
    +        } else {
    +            this.a = 1;
    +            this.b = 0;
    +            this.c = 0;
    +            this.d = 1;
    +            this.e = 0;
    +            this.f = 0;
    +        }
    +    }
    +    (function (matrixproto) {
    +        /*\
    +         * Matrix.add
    +         [ method ]
    +         **
    +         * Adds the given matrix to existing one
    +         - a (number)
    +         - b (number)
    +         - c (number)
    +         - d (number)
    +         - e (number)
    +         - f (number)
    +         * or
    +         - matrix (object) @Matrix
    +        \*/
    +        matrixproto.add = function (a, b, c, d, e, f) {
    +            var out = [[], [], []],
    +                m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],
    +                matrix = [[a, c, e], [b, d, f], [0, 0, 1]],
    +                x, y, z, res;
    +
    +            if (a && a instanceof Matrix) {
    +                matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]];
    +            }
    +
    +            for (x = 0; x < 3; x++) {
    +                for (y = 0; y < 3; y++) {
    +                    res = 0;
    +                    for (z = 0; z < 3; z++) {
    +                        res += m[x][z] * matrix[z][y];
    +                    }
    +                    out[x][y] = res;
    +                }
    +            }
    +            this.a = out[0][0];
    +            this.b = out[1][0];
    +            this.c = out[0][1];
    +            this.d = out[1][1];
    +            this.e = out[0][2];
    +            this.f = out[1][2];
    +            return this;
    +        };
    +        /*\
    +         * Matrix.invert
    +         [ method ]
    +         **
    +         * Returns an inverted version of the matrix
    +         = (object) @Matrix
    +        \*/
    +        matrixproto.invert = function () {
    +            var me = this,
    +                x = me.a * me.d - me.b * me.c;
    +            return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);
    +        };
    +        /*\
    +         * Matrix.clone
    +         [ method ]
    +         **
    +         * Returns a copy of the matrix
    +         = (object) @Matrix
    +        \*/
    +        matrixproto.clone = function () {
    +            return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
    +        };
    +        /*\
    +         * Matrix.translate
    +         [ method ]
    +         **
    +         * Translate the matrix
    +         - x (number) horizontal offset distance
    +         - y (number) vertical offset distance
    +        \*/
    +        matrixproto.translate = function (x, y) {
    +            return this.add(1, 0, 0, 1, x, y);
    +        };
    +        /*\
    +         * Matrix.scale
    +         [ method ]
    +         **
    +         * Scales the matrix
    +         - x (number) amount to be scaled, with `1` resulting in no change
    +         - y (number) #optional amount to scale along the vertical axis. (Otherwise `x` applies to both axes.)
    +         - cx (number) #optional horizontal origin point from which to scale
    +         - cy (number) #optional vertical origin point from which to scale
    +         * Default cx, cy is the middle point of the element.
    +        \*/
    +        matrixproto.scale = function (x, y, cx, cy) {
    +            y == null && (y = x);
    +            (cx || cy) && this.add(1, 0, 0, 1, cx, cy);
    +            this.add(x, 0, 0, y, 0, 0);
    +            (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);
    +            return this;
    +        };
    +        /*\
    +         * Matrix.rotate
    +         [ method ]
    +         **
    +         * Rotates the matrix
    +         - a (number) angle of rotation, in degrees
    +         - x (number) horizontal origin point from which to rotate
    +         - y (number) vertical origin point from which to rotate
    +        \*/
    +        matrixproto.rotate = function (a, x, y) {
    +            a = Snap.rad(a);
    +            x = x || 0;
    +            y = y || 0;
    +            var cos = +math.cos(a).toFixed(9),
    +                sin = +math.sin(a).toFixed(9);
    +            this.add(cos, sin, -sin, cos, x, y);
    +            return this.add(1, 0, 0, 1, -x, -y);
    +        };
    +        /*\
    +         * Matrix.x
    +         [ method ]
    +         **
    +         * Returns x coordinate for given point after transformation described by the matrix. See also @Matrix.y
    +         - x (number)
    +         - y (number)
    +         = (number) x
    +        \*/
    +        matrixproto.x = function (x, y) {
    +            return x * this.a + y * this.c + this.e;
    +        };
    +        /*\
    +         * Matrix.y
    +         [ method ]
    +         **
    +         * Returns y coordinate for given point after transformation described by the matrix. See also @Matrix.x
    +         - x (number)
    +         - y (number)
    +         = (number) y
    +        \*/
    +        matrixproto.y = function (x, y) {
    +            return x * this.b + y * this.d + this.f;
    +        };
    +        matrixproto.get = function (i) {
    +            return +this[Str.fromCharCode(97 + i)].toFixed(4);
    +        };
    +        matrixproto.toString = function () {
    +            return "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")";
    +        };
    +        matrixproto.offset = function () {
    +            return [this.e.toFixed(4), this.f.toFixed(4)];
    +        };
    +        function norm(a) {
    +            return a[0] * a[0] + a[1] * a[1];
    +        }
    +        function normalize(a) {
    +            var mag = math.sqrt(norm(a));
    +            a[0] && (a[0] /= mag);
    +            a[1] && (a[1] /= mag);
    +        }
    +        /*\
    +         * Matrix.determinant
    +         [ method ]
    +         **
    +         * Finds determinant of the given matrix.
    +         = (number) determinant
    +        \*/
    +        matrixproto.determinant = function () {
    +            return this.a * this.d - this.b * this.c;
    +        };
    +        /*\
    +         * Matrix.split
    +         [ method ]
    +         **
    +         * Splits matrix into primitive transformations
    +         = (object) in format:
    +         o dx (number) translation by x
    +         o dy (number) translation by y
    +         o scalex (number) scale by x
    +         o scaley (number) scale by y
    +         o shear (number) shear
    +         o rotate (number) rotation in deg
    +         o isSimple (boolean) could it be represented via simple transformations
    +        \*/
    +        matrixproto.split = function () {
    +            var out = {};
    +            // translation
    +            out.dx = this.e;
    +            out.dy = this.f;
    +
    +            // scale and shear
    +            var row = [[this.a, this.c], [this.b, this.d]];
    +            out.scalex = math.sqrt(norm(row[0]));
    +            normalize(row[0]);
    +
    +            out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1];
    +            row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear];
    +
    +            out.scaley = math.sqrt(norm(row[1]));
    +            normalize(row[1]);
    +            out.shear /= out.scaley;
    +
    +            if (this.determinant() < 0) {
    +                out.scalex = -out.scalex;
    +            }
    +
    +            // rotation
    +            var sin = -row[0][1],
    +                cos = row[1][1];
    +            if (cos < 0) {
    +                out.rotate = Snap.deg(math.acos(cos));
    +                if (sin < 0) {
    +                    out.rotate = 360 - out.rotate;
    +                }
    +            } else {
    +                out.rotate = Snap.deg(math.asin(sin));
    +            }
    +
    +            out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate);
    +            out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate;
    +            out.noRotation = !+out.shear.toFixed(9) && !out.rotate;
    +            return out;
    +        };
    +        /*\
    +         * Matrix.toTransformString
    +         [ method ]
    +         **
    +         * Returns transform string that represents given matrix
    +         = (string) transform string
    +        \*/
    +        matrixproto.toTransformString = function (shorter) {
    +            var s = shorter || this.split();
    +            if (!+s.shear.toFixed(9)) {
    +                s.scalex = +s.scalex.toFixed(4);
    +                s.scaley = +s.scaley.toFixed(4);
    +                s.rotate = +s.rotate.toFixed(4);
    +                return  (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) + 
    +                        (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) +
    +                        (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E);
    +            } else {
    +                return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)];
    +            }
    +        };
    +    })(Matrix.prototype);
    +    /*\
    +     * Snap.Matrix
    +     [ method ]
    +     **
    +     * Utility method
    +     **
    +     * Returns a matrix based on the given parameters
    +     - a (number)
    +     - b (number)
    +     - c (number)
    +     - d (number)
    +     - e (number)
    +     - f (number)
    +     * or
    +     - svgMatrix (SVGMatrix)
    +     = (object) @Matrix
    +    \*/
    +    Snap.Matrix = Matrix;
    +});
    \ No newline at end of file
    diff --git a/src/paper.js b/src/paper.js
    new file mode 100644
    index 0000000..9d0b703
    --- /dev/null
    +++ b/src/paper.js
    @@ -0,0 +1,695 @@
    +// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
    +// 
    +// Licensed under the Apache License, Version 2.0 (the "License");
    +// you may not use this file except in compliance with the License.
    +// You may obtain a copy of the License at
    +// 
    +// http://www.apache.org/licenses/LICENSE-2.0
    +// 
    +// Unless required by applicable law or agreed to in writing, software
    +// distributed under the License is distributed on an "AS IS" BASIS,
    +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +// See the License for the specific language governing permissions and
    +// limitations under the License.
    +Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
    +    var proto = Paper.prototype,
    +        is = Snap.is;
    +    /*\
    +     * Paper.rect
    +     [ method ]
    +     *
    +     * Draws a rectangle
    +     **
    +     - x (number) x coordinate of the top left corner
    +     - y (number) y coordinate of the top left corner
    +     - width (number) width
    +     - height (number) height
    +     - rx (number) #optional horizontal radius for rounded corners, default is 0
    +     - ry (number) #optional vertical radius for rounded corners, default is rx or 0
    +     = (object) the `rect` element
    +     **
    +     > Usage
    +     | // regular rectangle
    +     | var c = paper.rect(10, 10, 50, 50);
    +     | // rectangle with rounded corners
    +     | var c = paper.rect(40, 40, 50, 50, 10);
    +    \*/
    +    proto.rect = function (x, y, w, h, rx, ry) {
    +        var attr;
    +        if (ry == null) {
    +            ry = rx;
    +        }
    +        if (is(x, "object") && x == "[object Object]") {
    +            attr = x;
    +        } else if (x != null) {
    +            attr = {
    +                x: x,
    +                y: y,
    +                width: w,
    +                height: h
    +            };
    +            if (rx != null) {
    +                attr.rx = rx;
    +                attr.ry = ry;
    +            }
    +        }
    +        return this.el("rect", attr);
    +    };
    +    /*\
    +     * Paper.circle
    +     [ method ]
    +     **
    +     * Draws a circle
    +     **
    +     - x (number) x coordinate of the centre
    +     - y (number) y coordinate of the centre
    +     - r (number) radius
    +     = (object) the `circle` element
    +     **
    +     > Usage
    +     | var c = paper.circle(50, 50, 40);
    +    \*/
    +    proto.circle = function (cx, cy, r) {
    +        var attr;
    +        if (is(cx, "object") && cx == "[object Object]") {
    +            attr = cx;
    +        } else if (cx != null) {
    +            attr = {
    +                cx: cx,
    +                cy: cy,
    +                r: r
    +            };
    +        }
    +        return this.el("circle", attr);
    +    };
    +
    +    var preload = (function () {
    +        function onerror() {
    +            this.parentNode.removeChild(this);
    +        }
    +        return function (src, f) {
    +            var img = glob.doc.createElement("img"),
    +                body = glob.doc.body;
    +            img.style.cssText = "position:absolute;left:-9999em;top:-9999em";
    +            img.onload = function () {
    +                f.call(img);
    +                img.onload = img.onerror = null;
    +                body.removeChild(img);
    +            };
    +            img.onerror = onerror;
    +            body.appendChild(img);
    +            img.src = src;
    +        };
    +    }());
    +
    +    /*\
    +     * Paper.image
    +     [ method ]
    +     **
    +     * Places an image on the surface
    +     **
    +     - src (string) URI of the source image
    +     - x (number) x offset position
    +     - y (number) y offset position
    +     - width (number) width of the image
    +     - height (number) height of the image
    +     = (object) the `image` element
    +     * or
    +     = (object) Snap element object with type `image`
    +     **
    +     > Usage
    +     | var c = paper.image("apple.png", 10, 10, 80, 80);
    +    \*/
    +    proto.image = function (src, x, y, width, height) {
    +        var el = this.el("image");
    +        if (is(src, "object") && "src" in src) {
    +            el.attr(src);
    +        } else if (src != null) {
    +            var set = {
    +                "xlink:href": src,
    +                preserveAspectRatio: "none"
    +            };
    +            if (x != null && y != null) {
    +                set.x = x;
    +                set.y = y;
    +            }
    +            if (width != null && height != null) {
    +                set.width = width;
    +                set.height = height;
    +            } else {
    +                preload(src, function () {
    +                    Snap._.$(el.node, {
    +                        width: this.offsetWidth,
    +                        height: this.offsetHeight
    +                    });
    +                });
    +            }
    +            Snap._.$(el.node, set);
    +        }
    +        return el;
    +    };
    +    /*\
    +     * Paper.ellipse
    +     [ method ]
    +     **
    +     * Draws an ellipse
    +     **
    +     - x (number) x coordinate of the centre
    +     - y (number) y coordinate of the centre
    +     - rx (number) horizontal radius
    +     - ry (number) vertical radius
    +     = (object) the `ellipse` element
    +     **
    +     > Usage
    +     | var c = paper.ellipse(50, 50, 40, 20);
    +    \*/
    +    proto.ellipse = function (cx, cy, rx, ry) {
    +        var attr;
    +        if (is(cx, "object") && cx == "[object Object]") {
    +            attr = cx;
    +        } else if (cx != null) {
    +            attr ={
    +                cx: cx,
    +                cy: cy,
    +                rx: rx,
    +                ry: ry
    +            };
    +        }
    +        return this.el("ellipse", attr);
    +    };
    +    // SIERRA Paper.path(): Unclear from the link what a Catmull-Rom curveto is, and why it would make life any easier.
    +    /*\
    +     * Paper.path
    +     [ method ]
    +     **
    +     * Creates a `` element using the given string as the path's definition
    +     - pathString (string) #optional path string in SVG format
    +     * Path string consists of one-letter commands, followed by comma seprarated arguments in numerical form. Example:
    +     | "M10,20L30,40"
    +     * This example features two commands: `M`, with arguments `(10, 20)` and `L` with arguments `(30, 40)`. Uppercase letter commands express coordinates in absolute terms, while lowercase commands express them in relative terms from the most recently declared coordinates.
    +     *
    +     # 

    Here is short list of commands available, for more details see SVG path string format or article about path strings at MDN.

    + # + # + # + # + # + # + # + # + # + # + # + #
    CommandNameParameters
    Mmoveto(x y)+
    Zclosepath(none)
    Llineto(x y)+
    Hhorizontal linetox+
    Vvertical linetoy+
    Ccurveto(x1 y1 x2 y2 x y)+
    Ssmooth curveto(x2 y2 x y)+
    Qquadratic Bézier curveto(x1 y1 x y)+
    Tsmooth quadratic Bézier curveto(x y)+
    Aelliptical arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
    RCatmull-Rom curveto*x1 y1 (x y)+
    + * * _Catmull-Rom curveto_ is a not standard SVG command and added to make life easier. + * Note: there is a special case when a path consists of only three commands: `M10,10R…z`. In this case the path connects back to its starting point. + > Usage + | var c = paper.path("M10 10L90 90"); + | // draw a diagonal line: + | // move to 10,10, line to 90,90 + \*/ + proto.path = function (d) { + var attr; + if (is(d, "object") && !is(d, "array")) { + attr = d; + } else if (d) { + attr = {d: d}; + } + return this.el("path", attr); + }; + /*\ + * Paper.g + [ method ] + ** + * Creates a group element + ** + - varargs (…) #optional elements to nest within the group + = (object) the `g` element + ** + > Usage + | var c1 = paper.circle(), + | c2 = paper.rect(), + | g = paper.g(c2, c1); // note that the order of elements is different + * or + | var c1 = paper.circle(), + | c2 = paper.rect(), + | g = paper.g(); + | g.add(c2, c1); + \*/ + /*\ + * Paper.group + [ method ] + ** + * See @Paper.g + \*/ + proto.group = proto.g = function (first) { + var attr, + el = this.el("g"); + if (arguments.length == 1 && first && !first.type) { + el.attr(first); + } else if (arguments.length) { + el.add(Array.prototype.slice.call(arguments, 0)); + } + return el; + }; + /*\ + * Paper.svg + [ method ] + ** + * Creates a nested SVG element. + - x (number) @optional X of the element + - y (number) @optional Y of the element + - width (number) @optional width of the element + - height (number) @optional height of the element + - vbx (number) @optional viewbox X + - vby (number) @optional viewbox Y + - vbw (number) @optional viewbox width + - vbh (number) @optional viewbox height + ** + = (object) the `svg` element + ** + \*/ + proto.svg = function (x, y, width, height, vbx, vby, vbw, vbh) { + var attrs = {}; + if (is(x, "object") && y == null) { + attrs = x; + } else { + if (x != null) { + attrs.x = x; + } + if (y != null) { + attrs.y = y; + } + if (width != null) { + attrs.width = width; + } + if (height != null) { + attrs.height = height; + } + if (vbx != null && vby != null && vbw != null && vbh != null) { + attrs.viewBox = [vbx, vby, vbw, vbh]; + } + } + return this.el("svg", attrs); + }; + /*\ + * Paper.mask + [ method ] + ** + * Equivalent in behaviour to @Paper.g, except it’s a mask. + ** + = (object) the `mask` element + ** + \*/ + proto.mask = function (first) { + var attr, + el = this.el("mask"); + if (arguments.length == 1 && first && !first.type) { + el.attr(first); + } else if (arguments.length) { + el.add(Array.prototype.slice.call(arguments, 0)); + } + return el; + }; + /*\ + * Paper.ptrn + [ method ] + ** + * Equivalent in behaviour to @Paper.g, except it’s a mask. + - x (number) @optional X of the element + - y (number) @optional Y of the element + - width (number) @optional width of the element + - height (number) @optional height of the element + - vbx (number) @optional viewbox X + - vby (number) @optional viewbox Y + - vbw (number) @optional viewbox width + - vbh (number) @optional viewbox height + ** + = (object) the `mask` element + ** + \*/ + proto.ptrn = function (x, y, width, height, vx, vy, vw, vh) { + if (is(x, "object")) { + var attr = x; + } else if (!arguments.length) { + attr = {patternUnits: "userSpaceOnUse"}; + } else { + attr = {}; + if (x != null) { + attr.x = x; + } + if (y != null) { + attr.y = y; + } + if (width != null) { + attr.width = width; + } + if (height != null) { + attr.height = height; + } + if (vbx != null && vby != null && vbw != null && vbh != null) { + attr.viewBox = [vbx, vby, vbw, vbh]; + } + } + return this.el("pattern", attr); + }; + /*\ + * Paper.use + [ method ] + ** + * Creates a element. + - id (string) @optional id of element to link + * or + - id (Element) @optional element to link + ** + = (object) the `use` element + ** + \*/ + proto.use = function (id) { + if (id != null) { + var el = make("use", this.node); + if (id instanceof Element) { + if (!id.attr("id")) { + id.attr({id: ID()}); + } + id = id.attr("id"); + } + return this.el("use", {"xlink:href": id}); + } else { + return Element.prototype.use.call(this); + } + }; + /*\ + * Paper.text + [ method ] + ** + * Draws a text string + ** + - x (number) x coordinate position + - y (number) y coordinate position + - text (string|array) The text string to draw or array of strings to nest within separate `` elements + = (object) the `text` element + ** + > Usage + | var t1 = paper.text(50, 50, "Snap"); + | var t2 = paper.text(50, 50, ["S","n","a","p"]); + | // Text path usage + | t1.attr({textpath: "M10,10L100,100"}); + | // or + | var pth = paper.path("M10,10L100,100"); + | t1.attr({textpath: pth}); + \*/ + proto.text = function (x, y, text) { + var attr = {}; + if (is(x, "object")) { + attr = x; + } else if (x != null) { + attr = { + x: x, + y: y, + text: text || "" + }; + } + return this.el("text", attr); + }; + /*\ + * Paper.line + [ method ] + ** + * Draws a line + ** + - x1 (number) x coordinate position of the start + - y1 (number) y coordinate position of the start + - x2 (number) x coordinate position of the end + - y2 (number) y coordinate position of the end + = (object) the `line` element + ** + > Usage + | var t1 = paper.line(50, 50, 100, 100); + \*/ + proto.line = function (x1, y1, x2, y2) { + var attr = {}; + if (is(x1, "object")) { + attr = x1; + } else if (x1 != null) { + attr = { + x1: x1, + x2: x2, + y1: y1, + y2: y2 + }; + } + return this.el("line", attr); + }; + /*\ + * Paper.polyline + [ method ] + ** + * Draws a polyline + ** + - points (array) array of points + * or + - varargs (…) points + = (object) the `polyline` element + ** + > Usage + | var p1 = paper.polyline([10, 10, 100, 100]); + | var p2 = paper.polyline(10, 10, 100, 100); + \*/ + proto.polyline = function (points) { + if (arguments.length > 1) { + points = Array.prototype.slice.call(arguments, 0); + } + var attr = {}; + if (is(points, "object") && !is(points, "array")) { + attr = points; + } else if (points != null) { + attr = {points: points}; + } + return this.el("polyline", attr); + }; + /*\ + * Paper.polygon + [ method ] + ** + * Draws a polygon. See @Paper.polyline + \*/ + proto.polygon = function (points) { + if (arguments.length > 1) { + points = Array.prototype.slice.call(arguments, 0); + } + var attr = {}; + if (is(points, "object") && !is(points, "array")) { + attr = points; + } else if (points != null) { + attr = {points: points}; + } + return this.el("polygon", attr); + }; + // gradients + (function () { + var $ = Snap._.$; + // gradients' helpers + function Gstops() { + return this.selectAll("stop"); + } + function GaddStop(color, offset) { + var stop = $("stop"), + attr = { + offset: +offset + "%" + }; + color = Snap.color(color); + attr["stop-color"] = color.hex; + if (color.opacity < 1) { + attr["stop-opacity"] = color.opacity; + } + $(stop, attr); + this.node.appendChild(stop); + return this; + } + function GgetBBox() { + if (this.type == "linearGradient") { + var x1 = $(this.node, "x1") || 0, + x2 = $(this.node, "x2") || 1, + y1 = $(this.node, "y1") || 0, + y2 = $(this.node, "y2") || 0; + return Snap._.box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1)); + } else { + var cx = this.node.cx || .5, + cy = this.node.cy || .5, + r = this.node.r || 0; + return Snap._.box(cx - r, cy - r, r * 2, r * 2); + } + } + function arrayFirstValue(arr) { + var res; + for (var i = 0, ii = arr.length; i < ii; i++) { + res = res || arr[i]; + if (res) { + return res; + } + } + } + function gradient(defs, str) { + var grad = arrayFirstValue(eve("snap.util.grad.parse", null, str)), + el; + if (!grad) { + return null; + } + grad.params.unshift(defs); + if (grad.type.toLowerCase() == "l") { + el = gradientLinear.apply(0, grad.params); + } else { + el = gradientRadial.apply(0, grad.params); + } + if (grad.type != grad.type.toLowerCase()) { + $(el.node, { + gradientUnits: "userSpaceOnUse" + }); + } + var stops = grad.stops, + len = stops.length, + start = 0, + j = 0; + function seed(i, end) { + var step = (end - start) / (i - j); + for (var k = j; k < i; k++) { + stops[k].offset = +(+start + step * (k - j)).toFixed(2); + } + j = i; + start = end; + } + len--; + for (var i = 0; i < len; i++) if ("offset" in stops[i]) { + seed(i, stops[i].offset); + } + stops[len].offset = stops[len].offset || 100; + seed(len, stops[len].offset); + for (i = 0; i <= len; i++) { + var stop = stops[i]; + el.addStop(stop.color, stop.offset); + } + return el; + } + function gradientLinear(defs, x1, y1, x2, y2) { + var el = Snap._.make("linearGradient", defs); + el.stops = Gstops; + el.addStop = GaddStop; + el.getBBox = GgetBBox; + if (x1 != null) { + $(el.node, { + x1: x1, + y1: y1, + x2: x2, + y2: y2 + }); + } + return el; + } + function gradientRadial(defs, cx, cy, r, fx, fy) { + var el = Snap._.make("radialGradient", defs); + el.stops = Gstops; + el.addStop = GaddStop; + el.getBBox = GgetBBox; + if (cx != null) { + $(el.node, { + cx: cx, + cy: cy, + r: r + }); + } + if (fx != null && fy != null) { + $(el.node, { + fx: fx, + fy: fy + }); + } + return el; + } + /*\ + * Paper.gradient + [ method ] + ** + * Creates a gradient element + ** + - gradient (string) gradient descriptor + > Gradient Descriptor + * The gradient descriptor is an expression formatted as + * follows: `()`. The `` can be + * either linear or radial. The uppercase `L` or `R` letters + * indicate absolute coordinates offset from the SVG surface. + * Lowercase `l` or `r` letters indicate coordinates + * calculated relative to the element to which the gradient is + * applied. Coordinates specify a linear gradient vector as + * `x1`, `y1`, `x2`, `y2`, or a radial gradient as `cx`, `cy`, + * `r` and optional `fx`, `fy` specifying a focal point away + * from the center of the circle. Specify `` as a list + * of dash-separated CSS color values. Each color may be + * followed by a custom offset value, separated with a colon + * character. + > Examples + * Linear gradient, relative from top-left corner to bottom-right + * corner, from black through red to white: + | var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff"); + * Linear gradient, absolute from (0, 0) to (100, 100), from black + * through red at 25% to white: + | var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff"); + * Radial gradient, relative from the center of the element with radius + * half the width, from black to white: + | var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff"); + * To apply the gradient: + | paper.circle(50, 50, 40).attr({ + | fill: g + | }); + = (object) the `gradient` element + \*/ + proto.gradient = function (str) { + return gradient(this.defs, str); + }; + proto.gradientLinear = function (x1, y1, x2, y2) { + return gradientLinear(this.defs, x1, y1, x2, y2); + }; + proto.gradientRadial = function (cx, cy, r, fx, fy) { + return gradientRadial(this.defs, cx, cy, r, fx, fy); + }; + /*\ + * Paper.toString + [ method ] + ** + * Returns SVG code for the @Paper + = (string) SVG code for the @Paper + \*/ + proto.toString = function () { + var doc = this.node.ownerDocument, + f = doc.createDocumentFragment(), + d = doc.createElement("div"), + svg = this.node.cloneNode(true), + res; + f.appendChild(d); + d.appendChild(svg); + Snap._.$(svg, {xmlns: "http://www.w3.org/2000/svg"}); + res = d.innerHTML; + f.removeChild(f.firstChild); + return res; + }; + /*\ + * Paper.clear + [ method ] + ** + * Removes all child nodes of the paper, except . + \*/ + proto.clear = function () { + var node = this.node.firstChild, + next; + while (node) { + next = node.nextSibling; + if (node.tagName != "defs") { + node.parentNode.removeChild(node); + } else { + proto.clear.call({node: node}); + } + node = next; + } + }; + }()); +}); \ No newline at end of file diff --git a/src/svg.js b/src/svg.js index e7ca35d..05530ff 100644 --- a/src/svg.js +++ b/src/svg.js @@ -78,7 +78,7 @@ var has = "hasOwnProperty", bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, reURLValue = /^url\(#?([^)]+)\)$/, spaces = "\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029", - separator = new RegExp("[," + spaces + "]+"), + separator = Snap._.separator = new RegExp("[," + spaces + "]+"), whitespace = new RegExp("[" + spaces + "]", "g"), commaSpaces = new RegExp("[" + spaces + "]*,[" + spaces + "]*"), hsrg = {hs: 1, rg: 1}, @@ -209,24 +209,6 @@ Snap.format = (function () { }); }; })(); -var preload = (function () { - function onerror() { - this.parentNode.removeChild(this); - } - return function (src, f) { - var img = glob.doc.createElement("img"), - body = glob.doc.body; - img.style.cssText = "position:absolute;left:-9999em;top:-9999em"; - img.onload = function () { - f.call(img); - img.onload = img.onerror = null; - body.removeChild(img); - }; - img.onerror = onerror; - body.appendChild(img); - img.src = src; - }; -}()); function clone(obj) { if (typeof obj == "function" || Object(obj) !== obj) { return obj; @@ -304,7 +286,6 @@ Snap.rad = rad; = (number) angle in degrees \*/ Snap.deg = deg; -// SIERRA for which point is the angle calculated? /*\ * Snap.angle [ method ] @@ -359,288 +340,6 @@ Snap.snapTo = function (values, value, tolerance) { } return value; }; - -// MATRIX -function Matrix(a, b, c, d, e, f) { - if (b == null && objectToString.call(a) == "[object SVGMatrix]") { - this.a = a.a; - this.b = a.b; - this.c = a.c; - this.d = a.d; - this.e = a.e; - this.f = a.f; - return; - } - if (a != null) { - this.a = +a; - this.b = +b; - this.c = +c; - this.d = +d; - this.e = +e; - this.f = +f; - } else { - this.a = 1; - this.b = 0; - this.c = 0; - this.d = 1; - this.e = 0; - this.f = 0; - } -} -(function (matrixproto) { - /*\ - * Matrix.add - [ method ] - ** - * Adds the given matrix to existing one - - a (number) - - b (number) - - c (number) - - d (number) - - e (number) - - f (number) - * or - - matrix (object) @Matrix - \*/ - matrixproto.add = function (a, b, c, d, e, f) { - var out = [[], [], []], - m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], - matrix = [[a, c, e], [b, d, f], [0, 0, 1]], - x, y, z, res; - - if (a && a instanceof Matrix) { - matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]; - } - - for (x = 0; x < 3; x++) { - for (y = 0; y < 3; y++) { - res = 0; - for (z = 0; z < 3; z++) { - res += m[x][z] * matrix[z][y]; - } - out[x][y] = res; - } - } - this.a = out[0][0]; - this.b = out[1][0]; - this.c = out[0][1]; - this.d = out[1][1]; - this.e = out[0][2]; - this.f = out[1][2]; - return this; - }; - /*\ - * Matrix.invert - [ method ] - ** - * Returns an inverted version of the matrix - = (object) @Matrix - \*/ - matrixproto.invert = function () { - var me = this, - x = me.a * me.d - me.b * me.c; - return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x); - }; - /*\ - * Matrix.clone - [ method ] - ** - * Returns a copy of the matrix - = (object) @Matrix - \*/ - matrixproto.clone = function () { - return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f); - }; - /*\ - * Matrix.translate - [ method ] - ** - * Translate the matrix - - x (number) horizontal offset distance - - y (number) vertical offset distance - \*/ - matrixproto.translate = function (x, y) { - return this.add(1, 0, 0, 1, x, y); - }; - /*\ - * Matrix.scale - [ method ] - ** - * Scales the matrix - - x (number) amount to be scaled, with `1` resulting in no change - - y (number) #optional amount to scale along the vertical axis. (Otherwise `x` applies to both axes.) - - cx (number) #optional horizontal origin point from which to scale - - cy (number) #optional vertical origin point from which to scale - * Default cx, cy is the middle point of the element. - \*/ - matrixproto.scale = function (x, y, cx, cy) { - y == null && (y = x); - (cx || cy) && this.add(1, 0, 0, 1, cx, cy); - this.add(x, 0, 0, y, 0, 0); - (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy); - return this; - }; - /*\ - * Matrix.rotate - [ method ] - ** - * Rotates the matrix - - a (number) angle of rotation, in degrees - - x (number) horizontal origin point from which to rotate - - y (number) vertical origin point from which to rotate - \*/ - matrixproto.rotate = function (a, x, y) { - a = rad(a); - x = x || 0; - y = y || 0; - var cos = +math.cos(a).toFixed(9), - sin = +math.sin(a).toFixed(9); - this.add(cos, sin, -sin, cos, x, y); - return this.add(1, 0, 0, 1, -x, -y); - }; - /*\ - * Matrix.x - [ method ] - ** - * Returns x coordinate for given point after transformation described by the matrix. See also @Matrix.y - - x (number) - - y (number) - = (number) x - \*/ - matrixproto.x = function (x, y) { - return x * this.a + y * this.c + this.e; - }; - /*\ - * Matrix.y - [ method ] - ** - * Returns y coordinate for given point after transformation described by the matrix. See also @Matrix.x - - x (number) - - y (number) - = (number) y - \*/ - matrixproto.y = function (x, y) { - return x * this.b + y * this.d + this.f; - }; - matrixproto.get = function (i) { - return +this[Str.fromCharCode(97 + i)].toFixed(4); - }; - matrixproto.toString = function () { - return "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")"; - }; - matrixproto.offset = function () { - return [this.e.toFixed(4), this.f.toFixed(4)]; - }; - function norm(a) { - return a[0] * a[0] + a[1] * a[1]; - } - function normalize(a) { - var mag = math.sqrt(norm(a)); - a[0] && (a[0] /= mag); - a[1] && (a[1] /= mag); - } - /*\ - * Matrix.determinant - [ method ] - ** - * Finds determinant of the given matrix. - = (number) determinant - \*/ - matrixproto.determinant = function () { - return this.a * this.d - this.b * this.c; - }; - /*\ - * Matrix.split - [ method ] - ** - * Splits matrix into primitive transformations - = (object) in format: - o dx (number) translation by x - o dy (number) translation by y - o scalex (number) scale by x - o scaley (number) scale by y - o shear (number) shear - o rotate (number) rotation in deg - o isSimple (boolean) could it be represented via simple transformations - \*/ - matrixproto.split = function () { - var out = {}; - // translation - out.dx = this.e; - out.dy = this.f; - - // scale and shear - var row = [[this.a, this.c], [this.b, this.d]]; - out.scalex = math.sqrt(norm(row[0])); - normalize(row[0]); - - out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1]; - row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear]; - - out.scaley = math.sqrt(norm(row[1])); - normalize(row[1]); - out.shear /= out.scaley; - - if (this.determinant() < 0) { - out.scalex = -out.scalex; - } - - // rotation - var sin = -row[0][1], - cos = row[1][1]; - if (cos < 0) { - out.rotate = deg(math.acos(cos)); - if (sin < 0) { - out.rotate = 360 - out.rotate; - } - } else { - out.rotate = deg(math.asin(sin)); - } - - out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate); - out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate; - out.noRotation = !+out.shear.toFixed(9) && !out.rotate; - return out; - }; - /*\ - * Matrix.toTransformString - [ method ] - ** - * Returns transform string that represents given matrix - = (string) transform string - \*/ - matrixproto.toTransformString = function (shorter) { - var s = shorter || this.split(); - if (!+s.shear.toFixed(9)) { - s.scalex = +s.scalex.toFixed(4); - s.scaley = +s.scaley.toFixed(4); - s.rotate = +s.rotate.toFixed(4); - return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) + - (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) + - (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E); - } else { - return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)]; - } - }; -})(Matrix.prototype); -/*\ - * Snap.Matrix - [ method ] - ** - * Utility method - ** - * Returns a matrix based on the given parameters - - a (number) - - b (number) - - c (number) - - d (number) - - e (number) - - f (number) - * or - - svgMatrix (SVGMatrix) - = (object) @Matrix -\*/ -Snap.Matrix = Matrix; // Colour /*\ * Snap.getRGB @@ -1178,7 +877,7 @@ Snap._.svgTransform2string = svgTransform2string; Snap._.rgTransform = new RegExp("^[a-z][" + spaces + "]*-?\\.?\\d", "i"); function transform2matrix(tstr, bbox) { var tdata = parseTransformString(tstr), - m = new Matrix; + m = new Snap.Matrix; if (tdata) { for (var i = 0, ii = tdata.length; i < ii; i++) { var t = tdata[i], @@ -1256,7 +955,7 @@ function extractTransform(el, tstr) { tstr = el.node.getAttribute("transform"); } if (!tstr) { - return new Matrix; + return new Snap.Matrix; } tstr = svgTransform2string(tstr); } else { @@ -1546,8 +1245,6 @@ function arrayFirstValue(arr) { } return el; }; -// SIERRA Element.getBBox(): Unclear why you would want to express the dimension of the box as a path. -// SIERRA Element.getBBox(): Unclear why you would want to use r0/r1/r2. Also, basic definitions: wouldn't the _smallest circle that can be enclosed_ be a zero-radius point? /*\ * Element.getBBox [ method ] @@ -1624,15 +1321,15 @@ function arrayFirstValue(arr) { var _ = this._; if (tstr == null) { var papa = this, - global = new Matrix(this.node.getCTM()), + global = new Snap.Matrix(this.node.getCTM()), local = extractTransform(this), ms = [local], - m = new Matrix, + m = new Snap.Matrix, i, localString = local.toTransformString(), string = Str(local) == Str(this.matrix) ? _.transform : localString; - while ((papa = papa.parent()) && papa.type != "svg") { + while (papa.type != "svg" && (papa = papa.parent())) { ms.push(extractTransform(papa)); } i = ms.length; @@ -1651,7 +1348,7 @@ function arrayFirstValue(arr) { toString: propString }; } - if (tstr instanceof Matrix) { + if (tstr instanceof Snap.Matrix) { this.matrix = tstr; } else { extractTransform(this, tstr); @@ -2519,7 +2216,6 @@ function arrayFirstValue(arr) { }; } }(Element.prototype)); -// SIERRA Snap.parse() accepts & returns a fragment, but there's no info on what it does in between. What if it doesn't parse? /*\ * Snap.parse [ method ] @@ -2648,1026 +2344,58 @@ function wrap(dom) { if (dom instanceof Element || dom instanceof Fragment) { return dom; } - if (dom.tagName == "svg") { + if (dom.tagName && dom.tagName.toLowerCase() == "svg") { return new Paper(dom); } - if (dom.tagName.toLowerCase() == "object" && dom.type == "image/svg+xml") { + if (dom.tagName && dom.tagName.toLowerCase() == "object" && dom.type == "image/svg+xml") { return new Paper(dom.contentDocument.getElementsByTagName("svg")[0]); } return new Element(dom); } -// gradients' helpers -function Gstops() { - return this.selectAll("stop"); -} -function GaddStop(color, offset) { - var stop = $("stop"), - attr = { - offset: +offset + "%" - }; - color = Snap.color(color); - attr["stop-color"] = color.hex; - if (color.opacity < 1) { - attr["stop-opacity"] = color.opacity; - } - $(stop, attr); - this.node.appendChild(stop); - return this; -} -function GgetBBox() { - if (this.type == "linearGradient") { - var x1 = $(this.node, "x1") || 0, - x2 = $(this.node, "x2") || 1, - y1 = $(this.node, "y1") || 0, - y2 = $(this.node, "y2") || 0; - return Snap._.box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1)); - } else { - var cx = this.node.cx || .5, - cy = this.node.cy || .5, - r = this.node.r || 0; - return Snap._.box(cx - r, cy - r, r * 2, r * 2); - } -} -function gradient(defs, str) { - var grad = arrayFirstValue(eve("snap.util.grad.parse", null, str)), - el; - if (!grad) { - return null; - } - grad.params.unshift(defs); - if (grad.type.toLowerCase() == "l") { - el = gradientLinear.apply(0, grad.params); - } else { - el = gradientRadial.apply(0, grad.params); - } - if (grad.type != grad.type.toLowerCase()) { - $(el.node, { - gradientUnits: "userSpaceOnUse" - }); - } - var stops = grad.stops, - len = stops.length, - start = 0, - j = 0; - function seed(i, end) { - var step = (end - start) / (i - j); - for (var k = j; k < i; k++) { - stops[k].offset = +(+start + step * (k - j)).toFixed(2); - } - j = i; - start = end; - } - len--; - for (var i = 0; i < len; i++) if ("offset" in stops[i]) { - seed(i, stops[i].offset); - } - stops[len].offset = stops[len].offset || 100; - seed(len, stops[len].offset); - for (i = 0; i <= len; i++) { - var stop = stops[i]; - el.addStop(stop.color, stop.offset); - } - return el; -} -function gradientLinear(defs, x1, y1, x2, y2) { - var el = make("linearGradient", defs); - el.stops = Gstops; - el.addStop = GaddStop; - el.getBBox = GgetBBox; - if (x1 != null) { - $(el.node, { - x1: x1, - y1: y1, - x2: x2, - y2: y2 - }); - } - return el; -} -function gradientRadial(defs, cx, cy, r, fx, fy) { - var el = make("radialGradient", defs); - el.stops = Gstops; - el.addStop = GaddStop; - el.getBBox = GgetBBox; - if (cx != null) { - $(el.node, { - cx: cx, - cy: cy, - r: r - }); - } - if (fx != null && fy != null) { - $(el.node, { - fx: fx, - fy: fy - }); - } - return el; -} -// Paper prototype methods -(function (proto) { - /*\ - * Paper.el - [ method ] - ** - * Creates an element on paper with a given name and no attributes - ** - - name (string) tag name - - attr (object) attributes - = (Element) the current element - > Usage - | var c = paper.circle(10, 10, 10); // is the same as... - | var c = paper.el("circle").attr({ - | cx: 10, - | cy: 10, - | r: 10 - | }); - | // and the same as - | var c = paper.el("circle", { - | cx: 10, - | cy: 10, - | r: 10 - | }); - \*/ - proto.el = function (name, attr) { - return make(name, this.node).attr(attr); - }; - /*\ - * Paper.rect - [ method ] - * - * Draws a rectangle - ** - - x (number) x coordinate of the top left corner - - y (number) y coordinate of the top left corner - - width (number) width - - height (number) height - - rx (number) #optional horizontal radius for rounded corners, default is 0 - - ry (number) #optional vertical radius for rounded corners, default is rx or 0 - = (object) the `rect` element - ** - > Usage - | // regular rectangle - | var c = paper.rect(10, 10, 50, 50); - | // rectangle with rounded corners - | var c = paper.rect(40, 40, 50, 50, 10); - \*/ - proto.rect = function (x, y, w, h, rx, ry) { - var attr; - if (ry == null) { - ry = rx; - } - if (is(x, "object") && x == "[object Object]") { - attr = x; - } else if (x != null) { - attr = { - x: x, - y: y, - width: w, - height: h - }; - if (rx != null) { - attr.rx = rx; - attr.ry = ry; - } - } - return this.el("rect", attr); - }; - /*\ - * Paper.circle - [ method ] - ** - * Draws a circle - ** - - x (number) x coordinate of the centre - - y (number) y coordinate of the centre - - r (number) radius - = (object) the `circle` element - ** - > Usage - | var c = paper.circle(50, 50, 40); - \*/ - proto.circle = function (cx, cy, r) { - var attr; - if (is(cx, "object") && cx == "[object Object]") { - attr = cx; - } else if (cx != null) { - attr = { - cx: cx, - cy: cy, - r: r - }; - } - return this.el("circle", attr); - }; - /*\ - * Paper.image - [ method ] - ** - * Places an image on the surface - ** - - src (string) URI of the source image - - x (number) x offset position - - y (number) y offset position - - width (number) width of the image - - height (number) height of the image - = (object) the `image` element - * or - = (object) Snap element object with type `image` - ** - > Usage - | var c = paper.image("apple.png", 10, 10, 80, 80); - \*/ - proto.image = function (src, x, y, width, height) { - var el = make("image", this.node); - if (is(src, "object") && "src" in src) { - el.attr(src); - } else if (src != null) { - var set = { - "xlink:href": src, - preserveAspectRatio: "none" - }; - if (x != null && y != null) { - set.x = x; - set.y = y; - } - if (width != null && height != null) { - set.width = width; - set.height = height; - } else { - preload(src, function () { - $(el.node, { - width: this.offsetWidth, - height: this.offsetHeight - }); - }); - } - $(el.node, set); - } - return el; - }; - /*\ - * Paper.ellipse - [ method ] - ** - * Draws an ellipse - ** - - x (number) x coordinate of the centre - - y (number) y coordinate of the centre - - rx (number) horizontal radius - - ry (number) vertical radius - = (object) the `ellipse` element - ** - > Usage - | var c = paper.ellipse(50, 50, 40, 20); - \*/ - proto.ellipse = function (cx, cy, rx, ry) { - var el = make("ellipse", this.node); - if (is(cx, "object") && cx == "[object Object]") { - el.attr(cx); - } else if (cx != null) { - el.attr({ - cx: cx, - cy: cy, - rx: rx, - ry: ry - }); - } - return el; - }; - // SIERRA Paper.path(): Unclear from the link what a Catmull-Rom curveto is, and why it would make life any easier. - /*\ - * Paper.path - [ method ] - ** - * Creates a `` element using the given string as the path's definition - - pathString (string) #optional path string in SVG format - * Path string consists of one-letter commands, followed by comma seprarated arguments in numerical form. Example: - | "M10,20L30,40" - * This example features two commands: `M`, with arguments `(10, 20)` and `L` with arguments `(30, 40)`. Uppercase letter commands express coordinates in absolute terms, while lowercase commands express them in relative terms from the most recently declared coordinates. - * - #

    Here is short list of commands available, for more details see SVG path string format or article about path strings at MDN.

    - # - # - # - # - # - # - # - # - # - # - # - #
    CommandNameParameters
    Mmoveto(x y)+
    Zclosepath(none)
    Llineto(x y)+
    Hhorizontal linetox+
    Vvertical linetoy+
    Ccurveto(x1 y1 x2 y2 x y)+
    Ssmooth curveto(x2 y2 x y)+
    Qquadratic Bézier curveto(x1 y1 x y)+
    Tsmooth quadratic Bézier curveto(x y)+
    Aelliptical arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
    RCatmull-Rom curveto*x1 y1 (x y)+
    - * * _Catmull-Rom curveto_ is a not standard SVG command and added to make life easier. - * Note: there is a special case when a path consists of only three commands: `M10,10R…z`. In this case the path connects back to its starting point. - > Usage - | var c = paper.path("M10 10L90 90"); - | // draw a diagonal line: - | // move to 10,10, line to 90,90 - \*/ - proto.path = function (d) { - var el = make("path", this.node); - if (is(d, "object") && !is(d, "array")) { - el.attr(d); - } else if (d) { - el.attr({ - d: d - }); - } - return el; - }; - /*\ - * Paper.g - [ method ] - ** - * Creates a group element - ** - - varargs (…) #optional elements to nest within the group - = (object) the `g` element - ** - > Usage - | var c1 = paper.circle(), - | c2 = paper.rect(), - | g = paper.g(c2, c1); // note that the order of elements is different - * or - | var c1 = paper.circle(), - | c2 = paper.rect(), - | g = paper.g(); - | g.add(c2, c1); - \*/ - /*\ - * Paper.group - [ method ] - ** - * See @Paper.g - \*/ - proto.group = proto.g = function (first) { - var el = make("g", this.node); - if (arguments.length == 1 && first && !first.type) { - el.attr(first); - } else if (arguments.length) { - el.add(Array.prototype.slice.call(arguments, 0)); - } - return el; - }; - /*\ - * Paper.svg - [ method ] - ** - * Creates a nested SVG element. - - x (number) @optional X of the element - - y (number) @optional Y of the element - - width (number) @optional width of the element - - height (number) @optional height of the element - - vbx (number) @optional viewbox X - - vby (number) @optional viewbox Y - - vbw (number) @optional viewbox width - - vbh (number) @optional viewbox height - ** - = (object) the `svg` element - ** - \*/ - proto.svg = function (x, y, width, height, vbx, vby, vbw, vbh) { - var el = make("svg", this.node), - attrs = {}; - if (is(x, "object") && y == null) { - attrs = x; - } else { - if (x != null) { - attrs.x = x; - } - if (y != null) { - attrs.y = y; - } - if (width != null) { - attrs.width = width; - } - if (height != null) { - attrs.height = height; - } - if (vbx != null && vby != null && vbw != null && vbh != null) { - attrs.viewBox = [vbx, vby, vbw, vbh]; - } - } - el.attr(attrs); - return el; - }; - /*\ - * Paper.mask - [ method ] - ** - * Equivalent in behaviour to @Paper.g, except it’s a mask. - ** - = (object) the `mask` element - ** - \*/ - proto.mask = function (first) { - var el = make("mask", this.node); - if (arguments.length == 1 && first && !first.type) { - el.attr(first); - } else if (arguments.length) { - el.add(Array.prototype.slice.call(arguments, 0)); - } - return el; - }; - /*\ - * Paper.ptrn - [ method ] - ** - * Equivalent in behaviour to @Paper.g, except it’s a mask. - - x (number) @optional X of the element - - y (number) @optional Y of the element - - width (number) @optional width of the element - - height (number) @optional height of the element - - vbx (number) @optional viewbox X - - vby (number) @optional viewbox Y - - vbw (number) @optional viewbox width - - vbh (number) @optional viewbox height - ** - = (object) the `mask` element - ** - \*/ - proto.ptrn = function (x, y, width, height, vx, vy, vw, vh) { - var el = make("pattern", this.node); - if (!arguments.length) { - var attr = {patternUnits: "userSpaceOnUse"}; - } else { - if (vx == null) { - vx = x; - vy = y; - vw = width; - vh = height; - } - attr = { - x: x, - y: y, - width: width, - height: height, - patternUnits: "userSpaceOnUse", - viewBox: [vx, vy, vw, vh].join(" ") - }; - } - if (is(x, "object")) { - attr = x; - } - el.attr(attr); - return el; - }; - /*\ - * Paper.use - [ method ] - ** - * Creates a element. - - id (string) @optional id of element to link - * or - - id (Element) @optional element to link - ** - = (object) the `use` element - ** - \*/ - proto.use = function (id) { - if (id != null) { - var el = make("use", this.node); - if (id instanceof Element) { - if (!id.attr("id")) { - id.attr({id: ID()}); - } - id = id.attr("id"); - } - id && el.attr({ - "xlink:href": id - }); - return el; - } else { - return Element.prototype.use.call(this); - } - }; - /*\ - * Paper.text - [ method ] - ** - * Draws a text string - ** - - x (number) x coordinate position - - y (number) y coordinate position - - text (string|array) The text string to draw or array of strings to nest within separate `` elements - = (object) the `text` element - ** - > Usage - | var t1 = paper.text(50, 50, "Snap"); - | var t2 = paper.text(50, 50, ["S","n","a","p"]); - | // Text path usage - | t1.attr({textpath: "M10,10L100,100"}); - | // or - | var pth = paper.path("M10,10L100,100"); - | t1.attr({textpath: pth}); - \*/ - proto.text = function (x, y, text) { - var el = make("text", this.node); - if (is(x, "object")) { - el.attr(x); - } else if (x != null) { - el.attr({ - x: x, - y: y, - text: text || "" - }); - } - return el; - }; - /*\ - * Paper.line - [ method ] - ** - * Draws a line - ** - - x1 (number) x coordinate position of the start - - y1 (number) y coordinate position of the start - - x2 (number) x coordinate position of the end - - y2 (number) y coordinate position of the end - = (object) the `line` element - ** - > Usage - | var t1 = paper.line(50, 50, 100, 100); - \*/ - proto.line = function (x1, y1, x2, y2) { - var el = make("line", this.node); - if (is(x1, "object")) { - el.attr(x1); - } else if (x1 != null) { - el.attr({ - x1: x1, - x2: x2, - y1: y1, - y2: y2 - }); - } - return el; - }; - /*\ - * Paper.polyline - [ method ] - ** - * Draws a polyline - ** - - points (array) array of points - * or - - varargs (…) points - = (object) the `polyline` element - ** - > Usage - | var p1 = paper.polyline([10, 10, 100, 100]); - | var p2 = paper.polyline(10, 10, 100, 100); - \*/ - proto.polyline = function (points) { - if (arguments.length > 1) { - points = Array.prototype.slice.call(arguments, 0); - } - var el = make("polyline", this.node); - if (is(points, "object") && !is(points, "array")) { - el.attr(points); - } else if (points != null) { - el.attr({ - points: points - }); - } - return el; - }; - /*\ - * Paper.polygon - [ method ] - ** - * Draws a polygon. See @Paper.polyline - \*/ - proto.polygon = function (points) { - if (arguments.length > 1) { - points = Array.prototype.slice.call(arguments, 0); - } - var el = make("polygon", this.node); - if (is(points, "object") && !is(points, "array")) { - el.attr(points); - } else if (points != null) { - el.attr({ - points: points - }); - } - return el; - }; - // gradients - (function () { - /*\ - * Paper.gradient - [ method ] - ** - * Creates a gradient element - ** - - gradient (string) gradient descriptor - > Gradient Descriptor - * The gradient descriptor is an expression formatted as - * follows: `()`. The `` can be - * either linear or radial. The uppercase `L` or `R` letters - * indicate absolute coordinates offset from the SVG surface. - * Lowercase `l` or `r` letters indicate coordinates - * calculated relative to the element to which the gradient is - * applied. Coordinates specify a linear gradient vector as - * `x1`, `y1`, `x2`, `y2`, or a radial gradient as `cx`, `cy`, - * `r` and optional `fx`, `fy` specifying a focal point away - * from the center of the circle. Specify `` as a list - * of dash-separated CSS color values. Each color may be - * followed by a custom offset value, separated with a colon - * character. - > Examples - * Linear gradient, relative from top-left corner to bottom-right - * corner, from black through red to white: - | var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff"); - * Linear gradient, absolute from (0, 0) to (100, 100), from black - * through red at 25% to white: - | var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff"); - * Radial gradient, relative from the center of the element with radius - * half the width, from black to white: - | var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff"); - * To apply the gradient: - | paper.circle(50, 50, 40).attr({ - | fill: g - | }); - = (object) the `gradient` element - \*/ - proto.gradient = function (str) { - return gradient(this.defs, str); - }; - proto.gradientLinear = function (x1, y1, x2, y2) { - return gradientLinear(this.defs, x1, y1, x2, y2); - }; - proto.gradientRadial = function (cx, cy, r, fx, fy) { - return gradientRadial(this.defs, cx, cy, r, fx, fy); - }; - /*\ - * Paper.toString - [ method ] - ** - * Returns SVG code for the @Paper - = (string) SVG code for the @Paper - \*/ - proto.toString = function () { - var f = glob.doc.createDocumentFragment(), - d = glob.doc.createElement("div"), - svg = this.node.cloneNode(true), - res; - f.appendChild(d); - d.appendChild(svg); - $(svg, {xmlns: xmlns}); - res = d.innerHTML; - f.removeChild(f.firstChild); - return res; - }; - /*\ - * Paper.clear - [ method ] - ** - * Removes all child nodes of the paper, except . - \*/ - proto.clear = function () { - var node = this.node.firstChild, - next; - while (node) { - next = node.nextSibling; - if (node.tagName != "defs") { - node.parentNode.removeChild(node); - } - node = next; - } - }; - }()); -}(Paper.prototype)); - -// simple ajax +Snap._.make = make; +Snap._.wrap = wrap; /*\ - * Snap.ajax + * Paper.el [ method ] ** - * Simple implementation of Ajax + * Creates an element on paper with a given name and no attributes ** - - url (string) URL - - postData (object|string) data for post request - - callback (function) callback - - scope (object) #optional scope of callback - * or - - url (string) URL - - callback (function) callback - - scope (object) #optional scope of callback - = (XMLHttpRequest) the XMLHttpRequest object, just in case + - name (string) tag name + - attr (object) attributes + = (Element) the current element + > Usage + | var c = paper.circle(10, 10, 10); // is the same as... + | var c = paper.el("circle").attr({ + | cx: 10, + | cy: 10, + | r: 10 + | }); + | // and the same as + | var c = paper.el("circle", { + | cx: 10, + | cy: 10, + | r: 10 + | }); \*/ -Snap.ajax = function (url, postData, callback, scope){ - var req = new XMLHttpRequest, - id = ID(); - if (req) { - if (is(postData, "function")) { - scope = callback; - callback = postData; - postData = null; - } else if (is(postData, "object")) { - var pd = []; - for (var key in postData) if (postData.hasOwnProperty(key)) { - pd.push(encodeURIComponent(key) + "=" + encodeURIComponent(postData[key])); - } - postData = pd.join("&"); - } - req.open((postData ? "POST" : "GET"), url, true); - if (postData) { - req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - } - if (callback) { - eve.once("snap.ajax." + id + ".0", callback); - eve.once("snap.ajax." + id + ".200", callback); - eve.once("snap.ajax." + id + ".304", callback); - } - req.onreadystatechange = function() { - if (req.readyState != 4) return; - eve("snap.ajax." + id + "." + req.status, scope, req); - }; - if (req.readyState == 4) { - return req; - } - req.send(postData); - return req; - } +Paper.prototype.el = function (name, attr) { + var el = make(name, this.node); + attr && el.attr(attr); + return el; }; -/*\ - * Snap.load - [ method ] - ** - * Loads external SVG file as a @Fragment (see @Snap.ajax for more advanced AJAX) - ** - - url (string) URL - - callback (function) callback - - scope (object) #optional scope of callback -\*/ -Snap.load = function (url, callback, scope) { - Snap.ajax(url, function (req) { - var f = Snap.parse(req.responseText); - scope ? callback.call(scope, f) : callback(f); - }); -}; - -// Attributes event handlers -eve.on("snap.util.attr.mask", function (value) { - if (value instanceof Element || value instanceof Fragment) { - eve.stop(); - if (value instanceof Fragment && value.node.childNodes.length == 1) { - value = value.node.firstChild; - getSomeDefs(this).appendChild(value); - value = wrap(value); - } - if (value.type == "mask") { - var mask = value; - } else { - mask = make("mask", getSomeDefs(this)); - mask.node.appendChild(value.node); - !mask.node.id && $(mask.node, { - id: mask.id - }); - } - $(this.node, { - mask: URL(mask.id) - }); - } -}); -(function (clipIt) { - eve.on("snap.util.attr.clip", clipIt); - eve.on("snap.util.attr.clip-path", clipIt); - eve.on("snap.util.attr.clipPath", clipIt); -}(function (value) { - if (value instanceof Element || value instanceof Fragment) { - eve.stop(); - if (value.type == "clipPath") { - var clip = value; - } else { - clip = make("clipPath", getSomeDefs(this)); - clip.node.appendChild(value.node); - !clip.node.id && $(clip.node, { - id: clip.id - }); - } - $(this.node, { - "clip-path": URL(clip.id) - }); - } -})); -function fillStroke(name) { - return function (value) { - eve.stop(); - if (value instanceof Fragment && value.node.childNodes.length == 1 && - (value.node.firstChild.tagName == "radialGradient" || - value.node.firstChild.tagName == "linearGradient" || - value.node.firstChild.tagName == "pattern")) { - value = value.node.firstChild; - getSomeDefs(this).appendChild(value); - value = wrap(value); - } - if (value instanceof Element) { - if (value.type == "radialGradient" || value.type == "linearGradient" - || value.type == "pattern") { - if (!value.node.id) { - $(value.node, { - id: value.id - }); - } - var fill = URL(value.node.id); - } else { - fill = value.attr(name); - } - } else { - fill = Snap.color(value); - if (fill.error) { - var grad = gradient(getSomeDefs(this), value); - if (grad) { - if (!grad.node.id) { - $(grad.node, { - id: grad.id - }); - } - fill = URL(grad.node.id); - } else { - fill = value; - } - } else { - fill = Str(fill); - } - } - var attrs = {}; - attrs[name] = fill; - $(this.node, attrs); - this.node.style[name] = E; - }; -} -eve.on("snap.util.attr.fill", fillStroke("fill")); -eve.on("snap.util.attr.stroke", fillStroke("stroke")); -var gradrg = /^([lr])(?:\(([^)]*)\))?(.*)$/i; -eve.on("snap.util.grad.parse", function parseGrad(string) { - string = Str(string); - var tokens = string.match(gradrg); - if (!tokens) { - return null; - } - var type = tokens[1], - params = tokens[2], - stops = tokens[3]; - params = params.split(/\s*,\s*/).map(function (el) { - return +el == el ? +el : el; - }); - if (params.length == 1 && params[0] == 0) { - params = []; - } - stops = stops.split("-"); - stops = stops.map(function (el) { - el = el.split(":"); - var out = { - color: el[0] - }; - if (el[1]) { - out.offset = parseFloat(el[1]); - } - return out; - }); - return { - type: type, - params: params, - stops: stops - }; -}); - -eve.on("snap.util.attr.d", function (value) { - eve.stop(); - if (is(value, "array") && is(value[0], "array")) { - value = Snap.path.toString.call(value); - } - value = Str(value); - if (value.match(/[ruo]/i)) { - value = Snap.path.toAbsolute(value); - } - $(this.node, {d: value}); -})(-1); -eve.on("snap.util.attr.#text", function (value) { - eve.stop(); - value = Str(value); - var txt = glob.doc.createTextNode(value); - while (this.node.firstChild) { - this.node.removeChild(this.node.firstChild); - } - this.node.appendChild(txt); -})(-1); -eve.on("snap.util.attr.path", function (value) { - eve.stop(); - this.attr({d: value}); -})(-1); -eve.on("snap.util.attr.class", function (value) { - eve.stop(); - this.node.className.baseVal = value; -})(-1); -eve.on("snap.util.attr.viewBox", function (value) { - var vb; - if (is(value, "object") && "x" in value) { - vb = [value.x, value.y, value.width, value.height].join(" "); - } else if (is(value, "array")) { - vb = value.join(" "); - } else { - vb = value; - } - $(this.node, { - viewBox: vb - }); - eve.stop(); -})(-1); -eve.on("snap.util.attr.transform", function (value) { - this.transform(value); - eve.stop(); -})(-1); -eve.on("snap.util.attr.r", function (value) { - if (this.type == "rect") { - eve.stop(); - $(this.node, { - rx: value, - ry: value - }); - } -})(-1); -eve.on("snap.util.attr.textpath", function (value) { - eve.stop(); - if (this.type == "text") { - var id, tp, node; - if (!value && this.textPath) { - tp = this.textPath; - while (tp.node.firstChild) { - this.node.appendChild(tp.node.firstChild); - } - tp.remove(); - delete this.textPath; - return; - } - if (is(value, "string")) { - var defs = getSomeDefs(this), - path = wrap(defs.parentNode).path(value); - defs.appendChild(path.node); - id = path.id; - path.attr({id: id}); - } else { - value = wrap(value); - if (value instanceof Element) { - id = value.attr("id"); - if (!id) { - id = value.id; - value.attr({id: id}); - } - } - } - if (id) { - tp = this.textPath; - node = this.node; - if (tp) { - tp.attr({"xlink:href": "#" + id}); - } else { - tp = $("textPath", { - "xlink:href": "#" + id - }); - while (node.firstChild) { - tp.appendChild(node.firstChild); - } - node.appendChild(tp); - this.textPath = wrap(tp); - } - } - } -})(-1); -eve.on("snap.util.attr.text", function (value) { - if (this.type == "text") { - var i = 0, - node = this.node, - tuner = function (chunk) { - var out = $("tspan"); - if (is(chunk, "array")) { - for (var i = 0; i < chunk.length; i++) { - out.appendChild(tuner(chunk[i])); - } - } else { - out.appendChild(glob.doc.createTextNode(chunk)); - } - out.normalize && out.normalize(); - return out; - }; - while (node.firstChild) { - node.removeChild(node.firstChild); - } - var tuned = tuner(value); - while (tuned.firstChild) { - node.appendChild(tuned.firstChild); - } - } - eve.stop(); -})(-1); // default +eve.on("snap.util.getattr", function () { + var att = eve.nt(); + att = att.substring(att.lastIndexOf(".") + 1); + var css = att.replace(/[A-Z]/g, function (letter) { + return "-" + letter.toLowerCase(); + }); + if (cssAttr[has](css)) { + return this.node.ownerDocument.defaultView.getComputedStyle(this.node, null).getPropertyValue(css); + } else { + return $(this.node, att); + } +}); var cssAttr = { "alignment-baseline": 0, "baseline-shift": 0, @@ -3749,134 +2477,77 @@ eve.on("snap.util.attr", function (value) { $(this.node, attr); } }); -eve.on("snap.util.getattr.transform", function () { - eve.stop(); - return this.transform(); -})(-1); -eve.on("snap.util.getattr.textpath", function () { - eve.stop(); - return this.textPath; -})(-1); -// Markers -(function () { - function getter(end) { - return function () { - eve.stop(); - var style = glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue("marker-" + end); - if (style == "none") { - return style; - } else { - return Snap(glob.doc.getElementById(style.match(reURLValue)[1])); +(function (proto) {}(Paper.prototype)); + +// simple ajax +/*\ + * Snap.ajax + [ method ] + ** + * Simple implementation of Ajax + ** + - url (string) URL + - postData (object|string) data for post request + - callback (function) callback + - scope (object) #optional scope of callback + * or + - url (string) URL + - callback (function) callback + - scope (object) #optional scope of callback + = (XMLHttpRequest) the XMLHttpRequest object, just in case +\*/ +Snap.ajax = function (url, postData, callback, scope){ + var req = new XMLHttpRequest, + id = ID(); + if (req) { + if (is(postData, "function")) { + scope = callback; + callback = postData; + postData = null; + } else if (is(postData, "object")) { + var pd = []; + for (var key in postData) if (postData.hasOwnProperty(key)) { + pd.push(encodeURIComponent(key) + "=" + encodeURIComponent(postData[key])); } - }; - } - function setter(end) { - return function (value) { - eve.stop(); - var name = "marker" + end.charAt(0).toUpperCase() + end.substring(1); - if (value == "" || !value) { - this.node.style[name] = "none"; - return; - } - if (value.type == "marker") { - var id = value.node.id; - if (!id) { - $(value.node, {id: value.id}); - } - this.node.style[name] = URL(id); - return; - } - }; - } - eve.on("snap.util.getattr.marker-end", getter("end"))(-1); - eve.on("snap.util.getattr.markerEnd", getter("end"))(-1); - eve.on("snap.util.getattr.marker-start", getter("start"))(-1); - eve.on("snap.util.getattr.markerStart", getter("start"))(-1); - eve.on("snap.util.getattr.marker-mid", getter("mid"))(-1); - eve.on("snap.util.getattr.markerMid", getter("mid"))(-1); - eve.on("snap.util.attr.marker-end", setter("end"))(-1); - eve.on("snap.util.attr.markerEnd", setter("end"))(-1); - eve.on("snap.util.attr.marker-start", setter("start"))(-1); - eve.on("snap.util.attr.markerStart", setter("start"))(-1); - eve.on("snap.util.attr.marker-mid", setter("mid"))(-1); - eve.on("snap.util.attr.markerMid", setter("mid"))(-1); -}()); -eve.on("snap.util.getattr.r", function () { - if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) { - eve.stop(); - return $(this.node, "rx"); - } -})(-1); -function textExtract(node) { - var out = []; - var children = node.childNodes; - for (var i = 0, ii = children.length; i < ii; i++) { - var chi = children[i]; - if (chi.nodeType == 3) { - out.push(chi.nodeValue); + postData = pd.join("&"); } - if (chi.tagName == "tspan") { - if (chi.childNodes.length == 1 && chi.firstChild.nodeType == 3) { - out.push(chi.firstChild.nodeValue); - } else { - out.push(textExtract(chi)); - } + req.open((postData ? "POST" : "GET"), url, true); + if (postData) { + req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); } + if (callback) { + eve.once("snap.ajax." + id + ".0", callback); + eve.once("snap.ajax." + id + ".200", callback); + eve.once("snap.ajax." + id + ".304", callback); + } + req.onreadystatechange = function() { + if (req.readyState != 4) return; + eve("snap.ajax." + id + "." + req.status, scope, req); + }; + if (req.readyState == 4) { + return req; + } + req.send(postData); + return req; } - return out; -} -eve.on("snap.util.getattr.text", function () { - if (this.type == "text" || this.type == "tspan") { - eve.stop(); - var out = textExtract(this.node); - return out.length == 1 ? out[0] : out; - } -})(-1); -eve.on("snap.util.getattr.#text", function () { - return this.node.textContent; -})(-1); -eve.on("snap.util.getattr.viewBox", function () { - eve.stop(); - var vb = $(this.node, "viewBox"); - if (vb) { - vb = vb.split(separator); - return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]); - } else { - return; - } -})(-1); -eve.on("snap.util.getattr.points", function () { - var p = $(this.node, "points"); - eve.stop(); - return p.split(separator); -}); -eve.on("snap.util.getattr.path", function () { - var p = $(this.node, "d"); - eve.stop(); - return p; -}); -eve.on("snap.util.getattr.class", function () { - return this.node.className.baseVal; -}); -function getFontSize() { - eve.stop(); - return this.node.style.fontSize; -} -eve.on("snap.util.getattr.fontSize", getFontSize)(-1); -eve.on("snap.util.getattr.font-size", getFontSize)(-1); -// default -eve.on("snap.util.getattr", function () { - var att = eve.nt(); - att = att.substring(att.lastIndexOf(".") + 1); - var css = att.replace(/[A-Z]/g, function (letter) { - return "-" + letter.toLowerCase(); +}; +/*\ + * Snap.load + [ method ] + ** + * Loads external SVG file as a @Fragment (see @Snap.ajax for more advanced AJAX) + ** + - url (string) URL + - callback (function) callback + - scope (object) #optional scope of callback +\*/ +Snap.load = function (url, callback, scope) { + Snap.ajax(url, function (req) { + var f = Snap.parse(req.responseText); + scope ? callback.call(scope, f) : callback(f); }); - if (cssAttr[has](css)) { - return glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue(css); - } else { - return $(this.node, att); - } -}); +}; var getOffset = function (elem) { var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, @@ -3927,7 +2598,7 @@ Snap.getElementByPoint = function (x, y) { [ method ] ** * Let you write plugins. You pass in a function with four arguments, like this: - | Snap.plugin(function (Snap, Element, Paper, global) { + | Snap.plugin(function (Snap, Element, Paper, global, Fragment) { | Snap.newmethod = function () {}; | Element.prototype.newmethod = function () {}; | Paper.prototype.newmethod = function () {}; @@ -3938,7 +2609,7 @@ Snap.getElementByPoint = function (x, y) { - f (function) your plugin body \*/ Snap.plugin = function (f) { - f(Snap, Element, Paper, glob); + f(Snap, Element, Paper, glob, Fragment); }; glob.win.Snap = Snap; return Snap; diff --git a/test/paper.js b/test/paper.js index 5027ff7..87893d0 100644 --- a/test/paper.js +++ b/test/paper.js @@ -65,15 +65,17 @@ describe("Paper methods", function () { it("Paper.svg(x, y)", function() { var c = paper.svg(100, 200); expect(c.node.nodeName).to.be("svg"); - expect(c.node.width.baseVal.value).to.be(100); - expect(c.node.height.baseVal.value).to.be(200); + expect(c.node.x.baseVal.value).to.be(100); + expect(c.node.y.baseVal.value).to.be(200); expect(c.node.parentNode).to.be(paper.node); }); - it("Paper.svg(x, y, viewbox)", function() { - var c = paper.svg(100, 200, 10, 20, 30, 40); + it("Paper.svg(x, y, w, h, viewbox)", function() { + var c = paper.svg(100, 200, 300, 400, 10, 20, 30, 40); expect(c.node.nodeName).to.be("svg"); - expect(c.node.width.baseVal.value).to.be(100); - expect(c.node.height.baseVal.value).to.be(200); + expect(c.node.x.baseVal.value).to.be(100); + expect(c.node.y.baseVal.value).to.be(200); + expect(c.node.width.baseVal.value).to.be(300); + expect(c.node.height.baseVal.value).to.be(400); expect(c.node.getAttribute("viewBox")).to.be("10 20 30 40"); expect(c.node.parentNode).to.be(paper.node); }); @@ -125,6 +127,7 @@ describe("Paper methods", function () { }); it("Paper.getBBox", function() { paper.circle(50, 50, 30); + console.log(paper.getBBox) var bb = paper.getBBox(); expect(bb.x).to.be(20); expect(bb.y).to.be(20); diff --git a/test/primitives.js b/test/primitives.js index ddcc0b0..a5f7a81 100644 --- a/test/primitives.js +++ b/test/primitives.js @@ -109,4 +109,33 @@ describe("Primitives creation", function () { expect(C.getAttribute("x")).to.be("10"); expect(C.textContent).to.be("test"); }); + it("creates a mask", function () { + var c = s.mask(); + var C = document.querySelector("mask"); + expect(C).to.not.be(null); + expect(C).to.be(c.node); + }); + it("creates a pattern", function () { + var c = s.ptrn(); + var C = document.querySelector("pattern"); + expect(C).to.not.be(null); + expect(C).to.be(c.node); + }); + it("creates a pattern(x, y)", function() { + var c = s.ptrn(100, 200); + expect(c.node.nodeName).to.be("pattern"); + expect(c.node.x.baseVal.value).to.be(100); + expect(c.node.y.baseVal.value).to.be(200); + expect(c.node.parentNode).to.be(s.node); + }); + it("creates a pattern(x, y, w, h, viewbox)", function() { + var c = s.ptrn(100, 200, 300, 400, 10, 20, 30, 40); + expect(c.node.nodeName).to.be("pattern"); + expect(c.node.x.baseVal.value).to.be(100); + expect(c.node.y.baseVal.value).to.be(200); + expect(c.node.width.baseVal.value).to.be(300); + expect(c.node.height.baseVal.value).to.be(400); + expect(c.node.getAttribute("viewBox")).to.be("10 20 30 40"); + expect(c.node.parentNode).to.be(s.node); + }); }); diff --git a/test/test.html b/test/test.html index 63208bf..43420d9 100644 --- a/test/test.html +++ b/test/test.html @@ -28,7 +28,7 @@
    - +