From f94872941f4f833e2f1feb88c2ef1c43d83a88b4 Mon Sep 17 00:00:00 2001 From: cjgammon Date: Wed, 12 Feb 2014 10:33:52 -0800 Subject: [PATCH] banner ad demo added --- demos/snap-ad/Gruntfile.js | 75 + demos/snap-ad/README.md | 13 + demos/snap-ad/SnapAd.tmproj | 109 + demos/snap-ad/package.json | 19 + demos/snap-ad/site/assets/computer.svg | 25 + .../site/assets/fonts/OpenSans-Light.ttf | Bin 0 -> 222412 bytes .../assets/fonts/SourceSansPro-Semibold.ttf | Bin 0 -> 149636 bytes demos/snap-ad/site/assets/heart.svg | 8 + demos/snap-ad/site/assets/phone.svg | 21 + demos/snap-ad/site/assets/tablet.svg | 21 + demos/snap-ad/site/backup.jpg | Bin 0 -> 34998 bytes demos/snap-ad/site/css/screen.css | 93 + demos/snap-ad/site/index.html | 184 + demos/snap-ad/site/index.min.html | 8947 +++++++++++++++++ demos/snap-ad/site/js/main.js | 8628 ++++++++++++++++ demos/snap-ad/site/js/vendor/modernizr.min.js | 4 + demos/snap-ad/site/js/vendor/require.js | 2019 ++++ demos/snap-ad/site/js/vendor/require.min.js | 36 + .../screen.scssc | Bin 0 -> 6370 bytes demos/snap-ad/src/assets/computer.svg | 25 + .../src/assets/fonts/OpenSans-Light.ttf | Bin 0 -> 222412 bytes .../assets/fonts/SourceSansPro-Semibold.ttf | Bin 0 -> 149636 bytes demos/snap-ad/src/assets/heart.svg | 8 + demos/snap-ad/src/assets/phone.svg | 21 + demos/snap-ad/src/assets/tablet.svg | 21 + demos/snap-ad/src/backup.jpg | Bin 0 -> 34998 bytes demos/snap-ad/src/config.rb | 24 + demos/snap-ad/src/css/screen.css | 93 + demos/snap-ad/src/index.html | 187 + demos/snap-ad/src/js/app/app.js | 269 + demos/snap-ad/src/js/app/burst.js | 52 + demos/snap-ad/src/js/app/device.js | 218 + demos/snap-ad/src/js/app/heart.js | 103 + demos/snap-ad/src/js/app/logo.js | 59 + demos/snap-ad/src/js/app/mesh.js | 143 + demos/snap-ad/src/js/main.js | 94 + demos/snap-ad/src/js/vendor/fss.js | 760 ++ demos/snap-ad/src/js/vendor/fss/Color.js | 34 + demos/snap-ad/src/js/vendor/fss/Core.js | 61 + demos/snap-ad/src/js/vendor/fss/Geometry.js | 24 + demos/snap-ad/src/js/vendor/fss/Light.js | 12 + demos/snap-ad/src/js/vendor/fss/Material.js | 9 + demos/snap-ad/src/js/vendor/fss/Math.js | 14 + demos/snap-ad/src/js/vendor/fss/Mesh.js | 62 + demos/snap-ad/src/js/vendor/fss/Object.js | 14 + demos/snap-ad/src/js/vendor/fss/Plane.js | 44 + demos/snap-ad/src/js/vendor/fss/Renderer.js | 27 + .../snap-ad/src/js/vendor/fss/SVGRenderer.js | 66 + demos/snap-ad/src/js/vendor/fss/Scene.js | 27 + demos/snap-ad/src/js/vendor/fss/Triangle.js | 41 + demos/snap-ad/src/js/vendor/fss/Vector3.js | 190 + demos/snap-ad/src/js/vendor/fss/Vector4.js | 74 + demos/snap-ad/src/js/vendor/fss/Vertex.js | 14 + demos/snap-ad/src/js/vendor/modernizr.min.js | 4 + demos/snap-ad/src/js/vendor/require.js | 2019 ++++ demos/snap-ad/src/js/vendor/require.min.js | 36 + demos/snap-ad/src/js/vendor/snap.svg-min.js | 20 + demos/snap-ad/src/js/vendor/snap.svg.js | 6925 +++++++++++++ demos/snap-ad/src/sass/screen.scss | 82 + 59 files changed, 32078 insertions(+) create mode 100644 demos/snap-ad/Gruntfile.js create mode 100644 demos/snap-ad/README.md create mode 100644 demos/snap-ad/SnapAd.tmproj create mode 100644 demos/snap-ad/package.json create mode 100644 demos/snap-ad/site/assets/computer.svg create mode 100644 demos/snap-ad/site/assets/fonts/OpenSans-Light.ttf create mode 100644 demos/snap-ad/site/assets/fonts/SourceSansPro-Semibold.ttf create mode 100644 demos/snap-ad/site/assets/heart.svg create mode 100644 demos/snap-ad/site/assets/phone.svg create mode 100644 demos/snap-ad/site/assets/tablet.svg create mode 100644 demos/snap-ad/site/backup.jpg create mode 100644 demos/snap-ad/site/css/screen.css create mode 100644 demos/snap-ad/site/index.html create mode 100644 demos/snap-ad/site/index.min.html create mode 100644 demos/snap-ad/site/js/main.js create mode 100644 demos/snap-ad/site/js/vendor/modernizr.min.js create mode 100644 demos/snap-ad/site/js/vendor/require.js create mode 100644 demos/snap-ad/site/js/vendor/require.min.js create mode 100644 demos/snap-ad/src/.sass-cache/7eb2e4ecfecd432261de95f74b5302c6e0956ac9/screen.scssc create mode 100644 demos/snap-ad/src/assets/computer.svg create mode 100755 demos/snap-ad/src/assets/fonts/OpenSans-Light.ttf create mode 100755 demos/snap-ad/src/assets/fonts/SourceSansPro-Semibold.ttf create mode 100644 demos/snap-ad/src/assets/heart.svg create mode 100644 demos/snap-ad/src/assets/phone.svg create mode 100644 demos/snap-ad/src/assets/tablet.svg create mode 100644 demos/snap-ad/src/backup.jpg create mode 100644 demos/snap-ad/src/config.rb create mode 100644 demos/snap-ad/src/css/screen.css create mode 100755 demos/snap-ad/src/index.html create mode 100644 demos/snap-ad/src/js/app/app.js create mode 100644 demos/snap-ad/src/js/app/burst.js create mode 100644 demos/snap-ad/src/js/app/device.js create mode 100644 demos/snap-ad/src/js/app/heart.js create mode 100644 demos/snap-ad/src/js/app/logo.js create mode 100644 demos/snap-ad/src/js/app/mesh.js create mode 100644 demos/snap-ad/src/js/main.js create mode 100755 demos/snap-ad/src/js/vendor/fss.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Color.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Core.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Geometry.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Light.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Material.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Math.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Mesh.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Object.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Plane.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Renderer.js create mode 100755 demos/snap-ad/src/js/vendor/fss/SVGRenderer.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Scene.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Triangle.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Vector3.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Vector4.js create mode 100755 demos/snap-ad/src/js/vendor/fss/Vertex.js create mode 100644 demos/snap-ad/src/js/vendor/modernizr.min.js create mode 100644 demos/snap-ad/src/js/vendor/require.js create mode 100644 demos/snap-ad/src/js/vendor/require.min.js create mode 100755 demos/snap-ad/src/js/vendor/snap.svg-min.js create mode 100755 demos/snap-ad/src/js/vendor/snap.svg.js create mode 100644 demos/snap-ad/src/sass/screen.scss diff --git a/demos/snap-ad/Gruntfile.js b/demos/snap-ad/Gruntfile.js new file mode 100644 index 0000000..a0b5124 --- /dev/null +++ b/demos/snap-ad/Gruntfile.js @@ -0,0 +1,75 @@ +module.exports = function(grunt) { + + var pkg = grunt.file.readJSON("package.json"); + + // Project configuration. + grunt.initConfig({ + copy: { + main: { + files: [ + { + expand: true, + cwd: './src/', + src: [ + '*', + '!config.rb', + 'js/vendor/require.min.js', + 'js/vendor/modernizr.min.js' + ], + dest: './site/', + filter: 'isFile' + }, + { + expand: true, + cwd: './src', + src: ['assets/**'], + dest: './site/' + } + ] + } + }, + requirejs: { + compile: { + options: { + name: "main", + baseUrl: "./src/js/", + mainConfigFile: "./src/js/main.js", + out: "./site/js/main.js" + } + } + }, + compass: { + dist: { + options: { + config: './src/config.rb', + sassDir: './src/sass', + cssDir: './site/css' + } + } + }, + processhtml: { + options: { + // Task-specific options go here. + }, + dist: { + files: { + './site/index.html': ['./site/index.html'] + } + } + }, + inline: { + dist: { + src: ['./site/index.html'], + dest: ['./site/index.min.html'] + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-requirejs'); + grunt.loadNpmTasks("grunt-contrib-compass"); + grunt.loadNpmTasks("grunt-processhtml"); + grunt.loadNpmTasks("grunt-inline"); + + grunt.registerTask("default", ["copy", "requirejs", "compass", "processhtml", "inline"]); +}; \ No newline at end of file diff --git a/demos/snap-ad/README.md b/demos/snap-ad/README.md new file mode 100644 index 0000000..06a67b0 --- /dev/null +++ b/demos/snap-ad/README.md @@ -0,0 +1,13 @@ +snap-ad +======= + +Snap.svg banner ad + +run +`npm install` +to add node modules + + +run +`grunt` +to build \ No newline at end of file diff --git a/demos/snap-ad/SnapAd.tmproj b/demos/snap-ad/SnapAd.tmproj new file mode 100644 index 0000000..d5d2d56 --- /dev/null +++ b/demos/snap-ad/SnapAd.tmproj @@ -0,0 +1,109 @@ + + + + + currentDocument + src/js/app/app.js + documents + + + expanded + + name + src + regexFolderFilter + !.*/(\.[^/]*|CVS|_darcs|_MTN|\{arch\}|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$ + sourceDirectory + src + + + fileHierarchyDrawerWidth + 185 + metaData + + src/index.html + + caret + + column + 0 + line + 17 + + columnSelection + + firstVisibleColumn + 0 + firstVisibleLine + 3 + selectFrom + + column + 7 + line + 19 + + selectTo + + column + 0 + line + 17 + + + src/js/app/app.js + + caret + + column + 0 + line + 222 + + firstVisibleColumn + 0 + firstVisibleLine + 199 + + src/js/main.js + + caret + + column + 4 + line + 46 + + firstVisibleColumn + 0 + firstVisibleLine + 47 + + src/sass/screen.scss + + caret + + column + 2 + line + 81 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + + + openDocuments + + src/index.html + src/js/main.js + src/sass/screen.scss + src/js/app/app.js + + showFileHierarchyDrawer + + windowFrame + {{642, 51}, {651, 811}} + + diff --git a/demos/snap-ad/package.json b/demos/snap-ad/package.json new file mode 100644 index 0000000..1718196 --- /dev/null +++ b/demos/snap-ad/package.json @@ -0,0 +1,19 @@ +{ + "name": "snapad", + "version": "0.0.1", + "description": "snap ad", + "main": "Gruntfile.js", + "repository": { + "type": "git" + }, + "author": "CJ Gammon", + "license": "Apache License v2", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-copy": "*", + "grunt-contrib-compass": "*", + "grunt-contrib-requirejs": "*", + "grunt-processhtml": "*", + "grunt-inline": "*" + } +} diff --git a/demos/snap-ad/site/assets/computer.svg b/demos/snap-ad/site/assets/computer.svg new file mode 100644 index 0000000..05c5c57 --- /dev/null +++ b/demos/snap-ad/site/assets/computer.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/site/assets/fonts/OpenSans-Light.ttf b/demos/snap-ad/site/assets/fonts/OpenSans-Light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0d381897da20345fa63112f19042561f44ee3aa0 GIT binary patch literal 222412 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%0AG%b#%#Weyp=oz<}IGPqm z)8c4aT%)1Wt!Z(MiMFk2@iJ>#98HU(X>l|yj;6)Yv^bg;N7LeHS{zM_Yxd#ySkvN~ zeHg82+}v^bg;*NE&CYg!yli=%0AG%cHosL)|1w>IGPqm)8c4a98HU( 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

    ;uKu%NE38 z3$lVOND^C+$!tNUK!fHX1zC-$Y&DXhFAI=vA-*YWHP+C22*fGEcMaQ)9JU>6*mkUC z+fl)`V+PxfWo$cA*>j^jje#jUMgm=uBNiCrm?QB!`+OZ1qRa99M;ktXz2}ND(ffp4}Jmv-^ky< z=Xv?On9o|e2(9ozk z`wt7n9Nd9eB<8Xvm$N3PvnET{;cVO!w+0eSI-J8=n!{R}&03nnT3U)b;kF_U>FRRU z)hgE2BIxS5=pm7o7U?$K1~=(y26VL>Zqm{s*3v50(jwNDiRYiTC56q3zaI*zq8i?wt-?pIqZs#rf4;C3~yn1}n-d}1-{r$^Aa6j;kC zeJMBvBjyaT8b~cZI74hI9_9?OY-kp>+e@H3v&g2x z0(hY1i=f3m=;La%&9&%X(2dnw#W^@Ni|)54YIC4-=EO4Ui{!#8EQZ#XLVHibnI7wL zuk5Kfx$6vZF7AFk5AD54N(eTHV}`e3XEL0GdkXrUX$PhWQK&0LzlR3@aF} zW?02=17LYl1H)E^TN$3quq!m&7E0=67-V<>!}l}1l#W_Vx{~2F3~yq18^gQl;OwLa z89u`B35HKIq_y(sXt91D|Cxq%nc^S&i4z?dV`7*Dn~?+^Pk{!K&3Jcj5`6=rIx*Df zzh|M}E}-Wp=8~{kgl{ZpcoPdVIsRCX?4e|IIy03*XL9IF4xO3ifzPZo zI1th70Rv(u(Aq*;d9X_*X@38wY}=A?EpJeT2ChICF>&M``5N{dzd z7_&{nh?KbY&fF3`P2yT2n2WZp9xc+DXj}SmuG2*r@m+-*c5g&K?{={pBkM4o{2Un;{5;5D)yn1MaD4U&py#v1buPa|tbp($`9Zi97gmgk`i zh%4ztAA0WL5UIXy(yBYm(`mBL^UO1uPZSg~d7gb=&FOUV%H;awv#lR-7&wz}u+Qu5 z^G^G`$3CC3&nHK`KW*QivCn7i6DNrf-joIQxzf;{(qx`lR~rAUPYao~UzZVteV7VK zpNICm813vzu?{>*RficK1)Rk0Nw|wxiFxdv$L>OQ7sAav&AJ=d9%TGwj&<)gCR z%YKG)b8W0|BIb>p&ciOUB^Bt!B;iRjU~@#iUVstlA)OESmM#E1qCq9HSp-OX^3ow~ zD22x9orqV+@or;-8U}3I_7Q5|KYoqF*opI-1q!3+#-D|MiMG>rN}zg{mY0^ zEFS-Vwiex+v+w1bv#Ayz#GJ>!>)z~Fabxyt3GdAQuhyczTd4GBM3y>Jou$rJ=is!< z08YJYR~@QTb*mnneYp)Wb|XfEYE(_?RMo6na4zO1wOMV!>6mAz(-cm0gidsr2uP*{V${@yNip?Z&c zuX-QO(EWhANPSRUtS-T6x*t-PsSm5m)fK>XIcAJh`Xo?^6H{?+UpY?aU8a_+6>6ng zrPipmIM?$e#6TlXv`4~A%*9KMR*8oq}4 zRGGdS)TLT`jZ?@mFLMK63DPZ+1DH*CCpXpq`>f^vzwF{iFcb3$oC^6#eKlrdKCM5a zuhE~=*Xhse>-87(4f>1vM*Ssylm4>4S>J-QBfp9nn(yfE>hI}0^!IU&=nKRl^s$vp zm09Rz&yXIuAm)tlxO0W$&Ii99+H@;4^$uv|{m?f$8T?tfNA8mcDZ^C&NZ=hBa-2_3VcgyAT%ZGL-OYb*;KV{eRtE2|QI>+qd@F=CMqf z527;eb0~xmDiO(4NjZ*#V|LClr7~2SDV1ANQ7CRSY1CXQL@5nIDv4%wNw9OqCYXqhT+oz!*OT82;2oQ5+{{r6z&Qbjk^KH zz+3~~Pl&q%a`9P!Jlum^zW|GX95Y6lheZPVVW37S^RZ~a1y~FqyfGd2VqjdzK0^;N z9+c)%m{=^702*}2g07J1wfMM8Tz;KLIn-N$tU?i3T z7=@(*Mq_D!G1yW-4z>)Ci!BG_Vd;S7C=c)m$_G4(b^#tky8(}*0>Bff5bz`_0<1uL z08b%OKc7a$fM>w&Vw7044=@gu0>+~X)#yCnFW3se zE!axHVssI(1YH9B6;%T6v=%xS$8RS*)21x_pyeo_XTgcKsBi|?qdcqBSu^oDdoNOxL9uv)x1WYO&|4^v2mRs$zTXMnd-%if=5Yh)EpQwOWa>6GWI93GI%+M@V6XwvPp`CI3SUQ~?YY=_I`7tDO$RR6( z<*^dD%Fkrh@N<~g_}R-^enzAYYE*@_3O-;TvCm+)pdqkbLa;)C7)1isE>M7{KU68| zuzrCS1?IzG%k(G)V9y8&oni|uQBVVdC?n)>MnYay4wHv|VGy@dhX_5qEgG)0GFWM2 z0S2NWTLC8Iu)+nnkg>`Z*ul>qUx93^4fKx8u-5Q%tJnDXnp%FQrjDPZ0k%Rrx5;++ zxhOHn>#9OKaBUzr1TiaMEQ_x}VLuA!N0`mJV!qI;omf6Z3J3OJ!ye=(SIlQ%Uy3=! z0=7^F`U)9!VdyKF(}wvu)ID$oNw)OE*^y@k^$zyp88A_d+zZN`1GT{?^3Bw0nDPJS zYQkL{2WLq`=FrmwECFJ%@EjEMkc?cC&jKJU6bltl1dSa5F$%Kx-5zef(hs1L{ySoIN2 z0cL$hQ?Wj*4^0Dx2_Pq68HT0<({SVrY!gB*}N+0891ITwtmJ@&&dUp?Sbq z0{H=J>1aObi_roY5l$$GWEcYf1=nlfi8Atg{p?+`vQE(9aCV$A^0#pb1O-761AJvLTqnZne>ZMOh@0CQtSY8@+ z9BhK+G7wFi5ET;Cm!e?Gf&v6XNK9V{LY--57{c>B2zSC@*cR1Y>M5!~F7n3>LRnl$ zuZ2UJjR*fHkw1jyu*z_`vK~gI zWE#hr9yPB{qFg(9mXQ3~O9W4e5DWO-qj=#$vY3|#O_7inf`XW=lsBw~?!gX@G@v>~ zGL2|v#CY-xaakk#a0Zu4HKERo4G3p5sWUmS?lLElYR}^E*gKh)7SbD4yAy-8!^i0iMh*%~^%dV3uNOI}hm5|VdpJdq<% zqP_UezU8}^j#oHiu64Uyj*Yo#@y2a(S8S`;`pX&As4dbT_GvGO9yg(&D!t=i4zPh-v#_kVLo6qN5g7+dqOxexP#d3eLY^Uv zcpi(UMyL!>O>SVr_tc_k5NhPt6j_DAuRYlj&DHJ+;`Z?)A<+Gkz)6B5;ti1=tVUj*S%!V4ZCpG zXy)8cau?z~j5@t?K(YD!MabG!D{QKDmQlEGp@7G7wB~EHqwK*Ri#uZ|!3r8|%wi&C@?5nLJ4p z`_vV?(k{2ZlH$I#X2hw-GxMF>{XVu!?J?L{!lK@~m)&`FQK9QJhkm8U z4#HXDcSDw?_=P3}I@bD6S>kzKc2Q;G+p6<1eA4eu{Ya$t@^7V@6s~~FEy(GKoOkUS zFQ=hp@f(|_mo6zrEd*Ui1gxc?pfEzXE-{+W8Y&YgT_J?Wi=Jp~9L3~D8}azmF=9qV z@HwU?i%>rP1wbmA5}`Q292v4gK3@#!gsHh9Z8$w( z{E#D_BDyUz@lEm^qU24;k&kVnY87s2LVjioie~LpSod5tOVlB~-2) z@sUwei_0uVe9$|%?SS&dj2CmV1xo8AW*oXfD-xNfxA61hg=#)7ds(BNCE5n)WJg}P zVivkoQzXOgc}t^@jat0Z3Oxm(`9q=REA$`sjl+KT5!oHM zTz*W?+tRDFReoBXdL>1Z4`+Tj;dSibG3Ud5nM;IyUcRw!3JQ>CT=$nOxcA`0!;1kT z)}FF2oT}$|F4t|>&s5p@q9=dD1rw)x_RP>(&NnkVqupoJuVN=%iGF{$c_gnX$`1}LiyL8^|SIr6@)!r?Hzgd3*9=2_nctoimJK1gZ`r(=vW@}z{-`)4_eV6tA zme>s@N@}XMHN4SEnj0JC`u6F~x{`StcY3mpId!EKdudJI)YJM)+$uMhNo{Yaw?7xm zZIcsO(r&Ypd)!3qx}S~ditN>|Jvw#d2P{S!@`Wqq155nDFyjw!L4pFKkD!qoG;lp) zETNk>I!`N|I&5^ufsWyVjv;M>aWs;st8Ho3}QjPU!E^9 zhwvf16huKh1+$EU*+HP}Gzj5Ap@_?6w%<}t-?uI!?Bey5(1vNF43dzf)L;dCt2z8Uei-4TP1;?%SiSd3?7C?k-li@B z>tl=E3%$=roa*cG(0aCI*S?%3(dvgYEFIg@H`DG%xO_65nUY;Q`kienZu6K`XR5`J ze;yPac=K)KZ`GsbgxXD6lJ-F9Ks3#pEh+I-ZF|h@=4%fEdLAv5!R{?=w*2UGy6Rcx z6ithr?kty#iD$;zMXP~L+6^{o&7e(^y54PmweRfsNc>*t78T{0KlGURr~UeXu7Fi< zznLU*?Qx4ClN9j1MfwX}K@yEGWAy(@SCA^4#UU+)>0erkT}*KchvOC6dmNl9r26x_ z7-Ak94{T{FHISZO8QGt1<>4hQUx(Z1e<{w+Zal+C6!)!iNsnuPXz#4G`Sk^T`|~^R zg_LL5y1ia*equzW_PfB@UGnrOSD*Z{l?B*cJ@s1WM=i|TimT|p2j*{`yLbE8nNo_c zvzr)}j_zvLM|z8AP5u09+4~^tsr#Zi9a$X9kJDqt2UJg*Q%O3-jYQ z`m!#*R^*+sOV?`_aao(Sc7x%Lcn6J;J9~NYO;Wz}HQsAXPB${II&Gg=S^3;V{N~%; zD&1?&G#>U@WBCBzvry~M=rW@#(UoUhm+Fdq5|+Lh9KB%km9+0xn&d z0fbq??qy?yqedNipwpb!u!&NV?y9ph$CjenQrDJPqZuM}|0umY;%v8pF4N?RQ(%PT z(~H4Uy@Cbf!xybmxcux;>!D{Y)XOo_wVQd(N9R2_ZKh$L@HF8_?O2?;yX39&rIq70 zNTt+|_}nrtF4Aqjl;ae;NXY}w&2tV;ye}Ff^I0{qJSAx#yZcM-Q3(b8x5>Vu*4um^ zD^$y-MhF<0OYR+)Y4GS!_uOK%Uq08s*h!^HtKwo`!Y22N=?BwR`gK{CyXPmG=o=-S zXr_wF#=Hns^1a?!Ncb46aFlY;ju)TAV?=X zVbDzRbUaFhpX{%f$MCaL{=J>}`^v?Vuz=eI%7yL;%d~T;Q9*oV!r<}! z-%p(tCz?S8nL{IJMi6-5+aH}jNEiF4K$zcv)gdQTbb>~FomCMQ!>k`THYg5Rztmgb zpO!2!f~;ReR?MCe&JKcQ!`Tel2)^@%8K8&TI4r6+bR=*fJ`qPBYMAn`8vaXrd+fpp55KXy7`O0-m@`%uljfdNS3UXa z@urJc%$J^jVHhSo{rKuJ{fhE})eoLK=f`ISO1Zs%ck8{-nXQ`-GnFqNDt%NW9^G+g z{HzO_tF!3_k^!slXx!b{F*2q{qP{G~--|cvM%iPp&C(C0=RGqk5^Cc#vDDFNox=OqGD%MtbvT9oJ5<$kLlMX-!pE$w)j0;y>*jXRb^b^ z<6cw!xLe&uljI&h54C&O`YKt`i;jcIPIgJly)|wb_gXb(V6k(;IH|j2VAQN8EhRTIP1e-6Dm*9{5xn8j$94 zTl2n3Q_ZIvhSw*@C@*>$U3{?1?TNI6$4B}3eY`DBqnD@Zs&0^*dccLbwj$rO z;j&|={c>tb4Mb+6s*PE;ZFwCM}o z#xlu{%ADT(a?K4UQR$ttD|8m|q-OWUsxWQpXp6RGs$}n|^oU#Ln_If!(>C%RWw`|@VeD3nK zFB!FM!T}P;45qL9T-tI4mOY2j@lMxvk9}!izy;azr>#*dm4Y;@8;^>e)bwhQ=v?#5L(KrA zME$3^cN#CqoV8pj-CZwgd`c+k*!D*`<;^<{^&DGv*-S{z!5oW4gLO}8raWKJH74zn z$AwY9lr)aP^3yPJNYM&^yLv*jH1q)scQ;8<&OaT>!esssOB+TdKVsCkj!|ghUkmW( z)T&<#qJlJO5E>?gDIGFvG`cBm?jPuIV^iz6-bR&`2fQ;Hn%0|yXV=Eo{e%uvGS2pW ziP7{jZQFd$+^L>$=~{Y3wr6W{-ZYwFnf7ZvlkAI%)WyNMCwo3*mNn5rN*vB^&!0DQ za#8K*M(fR1VV}=g)33U!x7`?-tVuaPN|hle=aaGQzOdt$o|-ZX`jm`zP9NdlRs8z_ zGgfr2Ag3os`ts{ynWg@7iVEeD6FB}4WR^wQHN8^Is!;O`(xjejci}qqaPw9jk*ZN> zjoIk1kck?2X8vzBZI$!tD%$F~>9Aydl~?ekJVlWsyCR5Pmlvyt{(i=2^lI(xSu%S> zgamUMi$q$F_$2gZvM*OOwW%u2>lPj-QYdKfrC2YjiM81N)6NwSPo^SUH2G=u$o~N; Cmj74) literal 0 HcmV?d00001 diff --git a/demos/snap-ad/site/assets/heart.svg b/demos/snap-ad/site/assets/heart.svg new file mode 100644 index 0000000..87fd258 --- /dev/null +++ b/demos/snap-ad/site/assets/heart.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/demos/snap-ad/site/assets/phone.svg b/demos/snap-ad/site/assets/phone.svg new file mode 100644 index 0000000..dbd26ca --- /dev/null +++ b/demos/snap-ad/site/assets/phone.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/site/assets/tablet.svg b/demos/snap-ad/site/assets/tablet.svg new file mode 100644 index 0000000..1783bb0 --- /dev/null +++ b/demos/snap-ad/site/assets/tablet.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/site/backup.jpg b/demos/snap-ad/site/backup.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e05cec7eb174f9af8b27c705ff395cd20ea288c GIT binary patch literal 34998 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

    X->BjGE64$W9Kqxg?62Tyj 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 + + + + + + + + Snap! SVG + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/site/index.min.html b/demos/snap-ad/site/index.min.html new file mode 100644 index 0000000..150dd28 --- /dev/null +++ b/demos/snap-ad/site/index.min.html @@ -0,0 +1,8947 @@ + + + + + + + + + Snap! SVG + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/site/js/main.js b/demos/snap-ad/site/js/main.js new file mode 100644 index 0000000..833e2cb --- /dev/null +++ b/demos/snap-ad/site/js/main.js @@ -0,0 +1,8628 @@ + +// Snap.svg 0.2.0 +// +// 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. +// +// build: 2013-12-23 +// 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. +// ┌────────────────────────────────────────────────────────────┐ \\ +// │ Eve 0.4.2 - JavaScript Events Library │ \\ +// ├────────────────────────────────────────────────────────────┤ \\ +// │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\ +// └────────────────────────────────────────────────────────────┘ \\ + +(function (glob) { + var version = "0.4.2", + has = "hasOwnProperty", + separator = /[\.\/]/, + wildcard = "*", + fun = function () {}, + numsort = function (a, b) { + return a - b; + }, + current_event, + stop, + events = {n: {}}, + /*\ + * eve + [ method ] + + * Fires event with given `name`, given scope and other parameters. + + > Arguments + + - name (string) name of the *event*, dot (`.`) or slash (`/`) separated + - scope (object) context for the event handlers + - varargs (...) the rest of arguments will be sent to event handlers + + = (object) array of returned values from the listeners + \*/ + eve = function (name, scope) { + name = String(name); + var e = events, + oldstop = stop, + args = Array.prototype.slice.call(arguments, 2), + listeners = eve.listeners(name), + z = 0, + f = false, + l, + indexed = [], + queue = {}, + out = [], + ce = current_event, + errors = []; + current_event = name; + stop = 0; + for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) { + indexed.push(listeners[i].zIndex); + if (listeners[i].zIndex < 0) { + queue[listeners[i].zIndex] = listeners[i]; + } + } + indexed.sort(numsort); + while (indexed[z] < 0) { + l = queue[indexed[z++]]; + out.push(l.apply(scope, args)); + if (stop) { + stop = oldstop; + return out; + } + } + for (i = 0; i < ii; i++) { + l = listeners[i]; + if ("zIndex" in l) { + if (l.zIndex == indexed[z]) { + out.push(l.apply(scope, args)); + if (stop) { + break; + } + do { + z++; + l = queue[indexed[z]]; + l && out.push(l.apply(scope, args)); + if (stop) { + break; + } + } while (l) + } else { + queue[l.zIndex] = l; + } + } else { + out.push(l.apply(scope, args)); + if (stop) { + break; + } + } + } + stop = oldstop; + current_event = ce; + return out.length ? out : null; + }; + // Undocumented. Debug only. + eve._events = events; + /*\ + * eve.listeners + [ method ] + + * Internal method which gives you array of all event handlers that will be triggered by the given `name`. + + > Arguments + + - name (string) name of the event, dot (`.`) or slash (`/`) separated + + = (array) array of event handlers + \*/ + eve.listeners = function (name) { + var names = name.split(separator), + e = events, + item, + items, + k, + i, + ii, + j, + jj, + nes, + es = [e], + out = []; + for (i = 0, ii = names.length; i < ii; i++) { + nes = []; + for (j = 0, jj = es.length; j < jj; j++) { + e = es[j].n; + items = [e[names[i]], e[wildcard]]; + k = 2; + while (k--) { + item = items[k]; + if (item) { + nes.push(item); + out = out.concat(item.f || []); + } + } + } + es = nes; + } + return out; + }; + + /*\ + * eve.on + [ method ] + ** + * Binds given event handler with a given name. You can use wildcards “`*`” for the names: + | eve.on("*.under.*", f); + | eve("mouse.under.floor"); // triggers f + * Use @eve to trigger the listener. + ** + > Arguments + ** + - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards + - f (function) event handler function + ** + = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment. + > Example: + | eve.on("mouse", eatIt)(2); + | eve.on("mouse", scream); + | eve.on("mouse", catchIt)(1); + * This will ensure that `catchIt()` function will be called before `eatIt()`. + * + * If you want to put your handler before non-indexed handlers, specify a negative value. + * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”. + \*/ + eve.on = function (name, f) { + name = String(name); + if (typeof f != "function") { + return function () {}; + } + var names = name.split(separator), + e = events; + for (var i = 0, ii = names.length; i < ii; i++) { + e = e.n; + e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}}); + } + e.f = e.f || []; + for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) { + return fun; + } + e.f.push(f); + return function (zIndex) { + if (+zIndex == +zIndex) { + f.zIndex = +zIndex; + } + }; + }; + /*\ + * eve.f + [ method ] + ** + * Returns function that will fire given event with optional arguments. + * Arguments that will be passed to the result function will be also + * concated to the list of final arguments. + | el.onclick = eve.f("click", 1, 2); + | eve.on("click", function (a, b, c) { + | console.log(a, b, c); // 1, 2, [event object] + | }); + > Arguments + - event (string) event name + - varargs (…) and any other arguments + = (function) possible event handler function + \*/ + eve.f = function (event) { + var attrs = [].slice.call(arguments, 1); + return function () { + eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0))); + }; + }; + /*\ + * eve.stop + [ method ] + ** + * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing. + \*/ + eve.stop = function () { + stop = 1; + }; + /*\ + * eve.nt + [ method ] + ** + * Could be used inside event handler to figure out actual name of the event. + ** + > Arguments + ** + - subname (string) #optional subname of the event + ** + = (string) name of the event, if `subname` is not specified + * or + = (boolean) `true`, if current event’s name contains `subname` + \*/ + eve.nt = function (subname) { + if (subname) { + return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event); + } + return current_event; + }; + /*\ + * eve.nts + [ method ] + ** + * Could be used inside event handler to figure out actual name of the event. + ** + ** + = (array) names of the event + \*/ + eve.nts = function () { + return current_event.split(separator); + }; + /*\ + * eve.off + [ method ] + ** + * Removes given function from the list of event listeners assigned to given name. + * If no arguments specified all the events will be cleared. + ** + > Arguments + ** + - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards + - f (function) event handler function + \*/ + /*\ + * eve.unbind + [ method ] + ** + * See @eve.off + \*/ + eve.off = eve.unbind = function (name, f) { + if (!name) { + eve._events = events = {n: {}}; + return; + } + var names = name.split(separator), + e, + key, + splice, + i, ii, j, jj, + cur = [events]; + for (i = 0, ii = names.length; i < ii; i++) { + for (j = 0; j < cur.length; j += splice.length - 2) { + splice = [j, 1]; + e = cur[j].n; + if (names[i] != wildcard) { + if (e[names[i]]) { + splice.push(e[names[i]]); + } + } else { + for (key in e) if (e[has](key)) { + splice.push(e[key]); + } + } + cur.splice.apply(cur, splice); + } + } + for (i = 0, ii = cur.length; i < ii; i++) { + e = cur[i]; + while (e.n) { + if (f) { + if (e.f) { + for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) { + e.f.splice(j, 1); + break; + } + !e.f.length && delete e.f; + } + for (key in e.n) if (e.n[has](key) && e.n[key].f) { + var funcs = e.n[key].f; + for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) { + funcs.splice(j, 1); + break; + } + !funcs.length && delete e.n[key].f; + } + } else { + delete e.f; + for (key in e.n) if (e.n[has](key) && e.n[key].f) { + delete e.n[key].f; + } + } + e = e.n; + } + } + }; + /*\ + * eve.once + [ method ] + ** + * Binds given event handler with a given name to only run once then unbind itself. + | eve.once("login", f); + | eve("login"); // triggers f + | eve("login"); // no listeners + * Use @eve to trigger the listener. + ** + > Arguments + ** + - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards + - f (function) event handler function + ** + = (function) same return function as @eve.on + \*/ + eve.once = function (name, f) { + var f2 = function () { + eve.unbind(name, f2); + return f.apply(this, arguments); + }; + return eve.on(name, f2); + }; + /*\ + * eve.version + [ property (string) ] + ** + * Current version of the library. + \*/ + eve.version = version; + eve.toString = function () { + return "You are running Eve " + version; + }; + (typeof module != "undefined" && module.exports) ? (module.exports = eve) : (typeof define != "undefined" ? (define("eve", [], function() { return eve; })) : (glob.eve = eve)); +})(this); + +(function (glob, factory) { + // AMD support + if (typeof define === "function" && define.amd) { + // Define as an anonymous module + define('snap',["eve"], function( eve ) { + return factory(glob, eve); + }); + } else { + // Browser globals (glob is window) + // Snap adds itself to window + factory(glob, glob.eve); + } +}(this, function (window, eve) { +// 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. +var mina = (function (eve) { + var animations = {}, + requestAnimFrame = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { + setTimeout(callback, 16); + }, + isArray = Array.isArray || function (a) { + return a instanceof Array || + Object.prototype.toString.call(a) == "[object Array]"; + }, + idgen = 0, + idprefix = "M" + (+new Date).toString(36), + ID = function () { + return idprefix + (idgen++).toString(36); + }, + diff = function (a, b, A, B) { + if (isArray(a)) { + res = []; + for (var i = 0, ii = a.length; i < ii; i++) { + res[i] = diff(a[i], b, A[i], B); + } + return res; + } + var dif = (A - a) / (B - b); + return function (bb) { + return a + dif * (bb - b); + }; + }, + timer = Date.now || function () { + return +new Date; + }, + sta = function (val) { + var a = this; + if (val == null) { + return a.s; + } + var ds = a.s - val; + a.b += a.dur * ds; + a.B += a.dur * ds; + a.s = val; + }, + speed = function (val) { + var a = this; + if (val == null) { + return a.spd; + } + a.spd = val; + }, + duration = function (val) { + var a = this; + if (val == null) { + return a.dur; + } + a.s = a.s * val / a.dur; + a.dur = val; + }, + stopit = function () { + var a = this; + delete animations[a.id]; + eve("mina.stop." + a.id, a); + }, + pause = function () { + var a = this; + if (a.pdif) { + return; + } + delete animations[a.id]; + a.pdif = a.get() - a.b; + }, + resume = function () { + var a = this; + if (!a.pdif) { + return; + } + a.b = a.get() - a.pdif; + delete a.pdif; + animations[a.id] = a; + }, + frame = function () { + var len = 0; + for (var i in animations) if (animations.hasOwnProperty(i)) { + var a = animations[i], + b = a.get(), + res; + len++; + a.s = (b - a.b) / (a.dur / a.spd); + if (a.s >= 1) { + delete animations[i]; + a.s = 1; + len--; + (function (a) { + setTimeout(function () { + eve("mina.finish." + a.id, a); + }); + }(a)); + } + if (isArray(a.start)) { + res = []; + for (var j = 0, jj = a.start.length; j < jj; j++) { + res[j] = +a.start[j] + + (a.end[j] - a.start[j]) * a.easing(a.s); + } + } else { + res = +a.start + (a.end - a.start) * a.easing(a.s); + } + a.set(res); + } + len && requestAnimFrame(frame); + }, + // SIERRA Unfamiliar with the word _slave_ in this context. Also, I don't know what _gereal_ means. Do you mean _general_? + /*\ + * mina + [ method ] + ** + * Generic animation of numbers + ** + - a (number) start _slave_ number + - A (number) end _slave_ number + - b (number) start _master_ number (start time in general case) + - B (number) end _master_ number (end time in gereal case) + - get (function) getter of _master_ number (see @mina.time) + - set (function) setter of _slave_ number + - easing (function) #optional easing function, default is @mina.linear + = (object) animation descriptor + o { + o id (string) animation id, + o start (number) start _slave_ number, + o end (number) end _slave_ number, + o b (number) start _master_ number, + o s (number) animation status (0..1), + o dur (number) animation duration, + o spd (number) animation speed, + o get (function) getter of _master_ number (see @mina.time), + o set (function) setter of _slave_ number, + o easing (function) easing function, default is @mina.linear, + o status (function) status getter/setter, + o speed (function) speed getter/setter, + o duration (function) duration getter/setter, + o stop (function) animation stopper + o } + \*/ + mina = function (a, A, b, B, get, set, easing) { + var anim = { + id: ID(), + start: a, + end: A, + b: b, + s: 0, + dur: B - b, + spd: 1, + get: get, + set: set, + easing: easing || mina.linear, + status: sta, + speed: speed, + duration: duration, + stop: stopit, + pause: pause, + resume: resume + }; + animations[anim.id] = anim; + var len = 0, i; + for (i in animations) if (animations.hasOwnProperty(i)) { + len++; + if (len == 2) { + break; + } + } + len == 1 && requestAnimFrame(frame); + return anim; + }; + /*\ + * mina.time + [ method ] + ** + * Returns the current time. Equivalent to: + | function () { + | return (new Date).getTime(); + | } + \*/ + mina.time = timer; + /*\ + * mina.getById + [ method ] + ** + * Returns an animation by its id + - id (string) animation's id + = (object) See @mina + \*/ + mina.getById = function (id) { + return animations[id] || null; + }; + + /*\ + * mina.linear + [ method ] + ** + * Default linear easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.linear = function (n) { + return n; + }; + /*\ + * mina.easeout + [ method ] + ** + * Easeout easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.easeout = function (n) { + return Math.pow(n, 1.7); + }; + /*\ + * mina.easein + [ method ] + ** + * Easein easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.easein = function (n) { + return Math.pow(n, .48); + }; + /*\ + * mina.easeinout + [ method ] + ** + * Easeinout easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.easeinout = function (n) { + if (n == 1) { + return 1; + } + if (n == 0) { + return 0; + } + var q = .48 - n / 1.04, + Q = Math.sqrt(.1734 + q * q), + x = Q - q, + X = Math.pow(Math.abs(x), 1 / 3) * (x < 0 ? -1 : 1), + y = -Q - q, + Y = Math.pow(Math.abs(y), 1 / 3) * (y < 0 ? -1 : 1), + t = X + Y + .5; + return (1 - t) * 3 * t * t + t * t * t; + }; + /*\ + * mina.backin + [ method ] + ** + * Backin easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.backin = function (n) { + if (n == 1) { + return 1; + } + var s = 1.70158; + return n * n * ((s + 1) * n - s); + }; + /*\ + * mina.backout + [ method ] + ** + * Backout easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.backout = function (n) { + if (n == 0) { + return 0; + } + n = n - 1; + var s = 1.70158; + return n * n * ((s + 1) * n + s) + 1; + }; + /*\ + * mina.elastic + [ method ] + ** + * Elastic easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.elastic = function (n) { + if (n == !!n) { + return n; + } + return Math.pow(2, -10 * n) * Math.sin((n - .075) * + (2 * Math.PI) / .3) + 1; + }; + /*\ + * mina.bounce + [ method ] + ** + * Bounce easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.bounce = function (n) { + var s = 7.5625, + p = 2.75, + l; + if (n < (1 / p)) { + l = s * n * n; + } else { + if (n < (2 / p)) { + n -= (1.5 / p); + l = s * n * n + .75; + } else { + if (n < (2.5 / p)) { + n -= (2.25 / p); + l = s * n * n + .9375; + } else { + n -= (2.625 / p); + l = s * n * n + .984375; + } + } + } + return l; + }; + window.mina = mina; + return mina; +})(typeof eve == "undefined" ? function () {} : eve); +// 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. + +var Snap = (function() { +Snap.version = "0.2.0"; +/*\ + * Snap + [ method ] + ** + * Creates a drawing surface or wraps existing SVG element. + ** + - width (number|string) width of surface + - height (number|string) height of surface + * or + - DOM (SVGElement) element to be wrapped into Snap structure + * or + - query (string) CSS query selector + = (object) @Element +\*/ +function Snap(w, h) { + if (w) { + if (w.tagName) { + return wrap(w); + } + if (w instanceof Element) { + return w; + } + if (h == null) { + w = glob.doc.querySelector(w); + return wrap(w); + } + } + w = w == null ? "100%" : w; + h = h == null ? "100%" : h; + return new Paper(w, h); +} +Snap.toString = function () { + return "Snap v" + this.version; +}; +Snap._ = {}; +var glob = { + win: window, + doc: window.document +}; +Snap._.glob = glob; +var has = "hasOwnProperty", + Str = String, + toFloat = parseFloat, + toInt = parseInt, + math = Math, + mmax = math.max, + mmin = math.min, + abs = math.abs, + pow = math.pow, + PI = math.PI, + round = math.round, + E = "", + S = " ", + objectToString = Object.prototype.toString, + ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i, + colourRegExp = /^\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, + 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 + "]+"), + whitespace = new RegExp("[" + spaces + "]", "g"), + commaSpaces = new RegExp("[" + spaces + "]*,[" + spaces + "]*"), + hsrg = {hs: 1, rg: 1}, + pathCommand = new RegExp("([a-z])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"), + tCommand = new RegExp("([rstm])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"), + pathValues = new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[" + spaces + "]*,?[" + spaces + "]*", "ig"), + idgen = 0, + idprefix = "S" + (+new Date).toString(36), + ID = function () { + return idprefix + (idgen++).toString(36); + }, + xlink = "http://www.w3.org/1999/xlink", + xmlns = "http://www.w3.org/2000/svg", + hub = {}, + URL = Snap.url = function (url) { + return "url('#" + url + "')"; + }; + +function $(el, attr) { + if (attr) { + if (typeof el == "string") { + el = $(el); + } + if (typeof attr == "string") { + if (attr.substring(0, 6) == "xlink:") { + return el.getAttributeNS(xlink, attr.substring(6)); + } + if (attr.substring(0, 4) == "xml:") { + return el.getAttributeNS(xmlns, attr.substring(4)); + } + return el.getAttribute(attr); + } + for (var key in attr) if (attr[has](key)) { + var val = Str(attr[key]); + if (val) { + if (key.substring(0, 6) == "xlink:") { + el.setAttributeNS(xlink, key.substring(6), val); + } else if (key.substring(0, 4) == "xml:") { + el.setAttributeNS(xmlns, key.substring(4), val); + } else { + el.setAttribute(key, val); + } + } else { + el.removeAttribute(key); + } + } + } else { + el = glob.doc.createElementNS(xmlns, el); + // el.style && (el.style.webkitTapHighlightColor = "rgba(0,0,0,0)"); + } + return el; +} +Snap._.$ = $; +Snap._.id = ID; +function getAttrs(el) { + var attrs = el.attributes, + name, + out = {}; + for (var i = 0; i < attrs.length; i++) { + if (attrs[i].namespaceURI == xlink) { + name = "xlink:"; + } else { + name = ""; + } + name += attrs[i].name; + out[name] = attrs[i].textContent; + } + return out; +} +function is(o, type) { + type = Str.prototype.toLowerCase.call(type); + if (type == "finite") { + return isFinite(o); + } + if (type == "array" && + (o instanceof Array || Array.isArray && Array.isArray(o))) { + return true; + } + return (type == "null" && o === null) || + (type == typeof o && o !== null) || + (type == "object" && o === Object(o)) || + objectToString.call(o).slice(8, -1).toLowerCase() == type; +} +/*\ + * Snap.format + [ method ] + ** + * Replaces construction of type `{}` to the corresponding argument + ** + - token (string) string to format + - json (object) object which properties are used as a replacement + = (string) formatted string + > Usage + | // this draws a rectangular shape equivalent to "M10,20h40v50h-40z" + | paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z", { + | x: 10, + | y: 20, + | dim: { + | width: 40, + | height: 50, + | "negative width": -40 + | } + | })); +\*/ +Snap.format = (function () { + var tokenRegex = /\{([^\}]+)\}/g, + objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties + replacer = function (all, key, obj) { + var res = obj; + key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) { + name = name || quotedName; + if (res) { + if (name in res) { + res = res[name]; + } + typeof res == "function" && isFunc && (res = res()); + } + }); + res = (res == null || res == obj ? all : res) + ""; + return res; + }; + return function (str, obj) { + return Str(str).replace(tokenRegex, function (all, key) { + return replacer(all, key, obj); + }); + }; +})(); +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; + } + var res = new obj.constructor; + for (var key in obj) if (obj[has](key)) { + res[key] = clone(obj[key]); + } + return res; +} +Snap._.clone = clone; +function repush(array, item) { + for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) { + return array.push(array.splice(i, 1)[0]); + } +} +function cacher(f, scope, postprocessor) { + function newf() { + var arg = Array.prototype.slice.call(arguments, 0), + args = arg.join("\u2400"), + cache = newf.cache = newf.cache || {}, + count = newf.count = newf.count || []; + if (cache[has](args)) { + repush(count, args); + return postprocessor ? postprocessor(cache[args]) : cache[args]; + } + count.length >= 1e3 && delete cache[count.shift()]; + count.push(args); + cache[args] = f.apply(scope, arg); + return postprocessor ? postprocessor(cache[args]) : cache[args]; + } + return newf; +} +Snap._.cacher = cacher; +function angle(x1, y1, x2, y2, x3, y3) { + if (x3 == null) { + var x = x1 - x2, + y = y1 - y2; + if (!x && !y) { + return 0; + } + return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360; + } else { + return angle(x1, y1, x3, y3) - angle(x2, y2, x3, y3); + } +} +function rad(deg) { + return deg % 360 * PI / 180; +} +function deg(rad) { + return rad * 180 / PI % 360; +} +function x_y() { + return this.x + S + this.y; +} +function x_y_w_h() { + return this.x + S + this.y + S + this.width + " \xd7 " + this.height; +} + +/*\ + * Snap.rad + [ method ] + ** + * Transform angle to radians + - deg (number) angle in degrees + = (number) angle in radians +\*/ +Snap.rad = rad; +/*\ + * Snap.deg + [ method ] + ** + * Transform angle to degrees + - rad (number) angle in radians + = (number) angle in degrees +\*/ +Snap.deg = deg; +// SIERRA for which point is the angle calculated? +/*\ + * Snap.angle + [ method ] + ** + * Returns an angle between two or three points + > Parameters + - x1 (number) x coord of first point + - y1 (number) y coord of first point + - x2 (number) x coord of second point + - y2 (number) y coord of second point + - x3 (number) #optional x coord of third point + - y3 (number) #optional y coord of third point + = (number) angle in degrees +\*/ +Snap.angle = angle; +/*\ + * Snap.is + [ method ] + ** + * Handy replacement for the `typeof` operator + - o (…) any object or primitive + - type (string) name of the type, e.g., `string`, `function`, `number`, etc. + = (boolean) `true` if given value is of given type +\*/ +Snap.is = is; +/*\ + * Snap.snapTo + [ method ] + ** + * Snaps given value to given grid + - values (array|number) given array of values or step of the grid + - value (number) value to adjust + - tolerance (number) #optional maximum distance to the target value that would trigger the snap. Default is `10`. + = (number) adjusted value +\*/ +Snap.snapTo = function (values, value, tolerance) { + tolerance = is(tolerance, "finite") ? tolerance : 10; + if (is(values, "array")) { + var i = values.length; + while (i--) if (abs(values[i] - value) <= tolerance) { + return values[i]; + } + } else { + values = +values; + var rem = value % values; + if (rem < tolerance) { + return value - rem; + } + if (rem > values - tolerance) { + return value - rem + values; + } + } + 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.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; + + // 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.isSimple) { + 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 + [ method ] + ** + * Parses color string as RGB object + - color (string) color string in one of the following formats: + #

    + * Note that `%` can be used any time: `rgb(20%, 255, 50%)`. + = (object) RGB object in the following format: + o { + o r (number) red, + o g (number) green, + o b (number) blue, + o hex (string) color in HTML/CSS format: #••••••, + o error (boolean) true if string can't be parsed + o } +\*/ +Snap.getRGB = cacher(function (colour) { + if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) { + return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString}; + } + if (colour == "none") { + return {r: -1, g: -1, b: -1, hex: "none", toString: rgbtoString}; + } + !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour)); + if (!colour) { + return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString}; + } + var res, + red, + green, + blue, + opacity, + t, + values, + rgb = colour.match(colourRegExp); + if (rgb) { + if (rgb[2]) { + blue = toInt(rgb[2].substring(5), 16); + green = toInt(rgb[2].substring(3, 5), 16); + red = toInt(rgb[2].substring(1, 3), 16); + } + if (rgb[3]) { + blue = toInt((t = rgb[3].charAt(3)) + t, 16); + green = toInt((t = rgb[3].charAt(2)) + t, 16); + red = toInt((t = rgb[3].charAt(1)) + t, 16); + } + if (rgb[4]) { + values = rgb[4].split(commaSpaces); + red = toFloat(values[0]); + values[0].slice(-1) == "%" && (red *= 2.55); + green = toFloat(values[1]); + values[1].slice(-1) == "%" && (green *= 2.55); + blue = toFloat(values[2]); + values[2].slice(-1) == "%" && (blue *= 2.55); + rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3])); + values[3] && values[3].slice(-1) == "%" && (opacity /= 100); + } + if (rgb[5]) { + values = rgb[5].split(commaSpaces); + red = toFloat(values[0]); + values[0].slice(-1) == "%" && (red /= 100); + green = toFloat(values[1]); + values[1].slice(-1) == "%" && (green /= 100); + blue = toFloat(values[2]); + values[2].slice(-1) == "%" && (blue /= 100); + (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); + rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3])); + values[3] && values[3].slice(-1) == "%" && (opacity /= 100); + return Snap.hsb2rgb(red, green, blue, opacity); + } + if (rgb[6]) { + values = rgb[6].split(commaSpaces); + red = toFloat(values[0]); + values[0].slice(-1) == "%" && (red /= 100); + green = toFloat(values[1]); + values[1].slice(-1) == "%" && (green /= 100); + blue = toFloat(values[2]); + values[2].slice(-1) == "%" && (blue /= 100); + (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); + rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3])); + values[3] && values[3].slice(-1) == "%" && (opacity /= 100); + return Snap.hsl2rgb(red, green, blue, opacity); + } + red = mmin(math.round(red), 255); + green = mmin(math.round(green), 255); + blue = mmin(math.round(blue), 255); + opacity = mmin(mmax(opacity, 0), 1); + rgb = {r: red, g: green, b: blue, toString: rgbtoString}; + rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1); + rgb.opacity = is(opacity, "finite") ? opacity : 1; + return rgb; + } + return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString}; +}, Snap); +// SIERRA It seems odd that the following 3 conversion methods are not expressed as .this2that(), like the others. +/*\ + * Snap.hsb + [ method ] + ** + * Converts HSB values to a hex representation of the color + - h (number) hue + - s (number) saturation + - b (number) value or brightness + = (string) hex representation of the color +\*/ +Snap.hsb = cacher(function (h, s, b) { + return Snap.hsb2rgb(h, s, b).hex; +}); +/*\ + * Snap.hsl + [ method ] + ** + * Converts HSL values to a hex representation of the color + - h (number) hue + - s (number) saturation + - l (number) luminosity + = (string) hex representation of the color +\*/ +Snap.hsl = cacher(function (h, s, l) { + return Snap.hsl2rgb(h, s, l).hex; +}); +/*\ + * Snap.rgb + [ method ] + ** + * Converts RGB values to a hex representation of the color + - r (number) red + - g (number) green + - b (number) blue + = (string) hex representation of the color +\*/ +Snap.rgb = cacher(function (r, g, b, o) { + if (is(o, "finite")) { + var round = math.round; + return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")"; + } + return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1); +}); +var toHex = function (color) { + var i = glob.doc.getElementsByTagName("head")[0], + red = "rgb(255, 0, 0)"; + toHex = cacher(function (color) { + if (color.toLowerCase() == "red") { + return red; + } + i.style.color = red; + i.style.color = color; + var out = glob.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color"); + return out == red ? null : out; + }); + return toHex(color); +}, +hsbtoString = function () { + return "hsb(" + [this.h, this.s, this.b] + ")"; +}, +hsltoString = function () { + return "hsl(" + [this.h, this.s, this.l] + ")"; +}, +rgbtoString = function () { + return this.opacity == 1 || this.opacity == null ? + this.hex : + "rgba(" + [this.r, this.g, this.b, this.opacity] + ")"; +}, +prepareRGB = function (r, g, b) { + if (g == null && is(r, "object") && "r" in r && "g" in r && "b" in r) { + b = r.b; + g = r.g; + r = r.r; + } + if (g == null && is(r, string)) { + var clr = Snap.getRGB(r); + r = clr.r; + g = clr.g; + b = clr.b; + } + if (r > 1 || g > 1 || b > 1) { + r /= 255; + g /= 255; + b /= 255; + } + + return [r, g, b]; +}, +packageRGB = function (r, g, b, o) { + r = math.round(r * 255); + g = math.round(g * 255); + b = math.round(b * 255); + var rgb = { + r: r, + g: g, + b: b, + opacity: is(o, "finite") ? o : 1, + hex: Snap.rgb(r, g, b), + toString: rgbtoString + }; + is(o, "finite") && (rgb.opacity = o); + return rgb; +}; +// SIERRA Clarify if Snap does not support consolidated HSLA/RGBA colors. E.g., can you specify a semi-transparent value for Snap.filter.shadow()? +/*\ + * Snap.color + [ method ] + ** + * Parses the color string and returns an object featuring the color's component values + - clr (string) color string in one of the supported formats (see @Snap.getRGB) + = (object) Combined RGB/HSB object in the following format: + o { + o r (number) red, + o g (number) green, + o b (number) blue, + o hex (string) color in HTML/CSS format: #••••••, + o error (boolean) `true` if string can't be parsed, + o h (number) hue, + o s (number) saturation, + o v (number) value (brightness), + o l (number) lightness + o } +\*/ +Snap.color = function (clr) { + var rgb; + if (is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) { + rgb = Snap.hsb2rgb(clr); + clr.r = rgb.r; + clr.g = rgb.g; + clr.b = rgb.b; + clr.opacity = 1; + clr.hex = rgb.hex; + } else if (is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) { + rgb = Snap.hsl2rgb(clr); + clr.r = rgb.r; + clr.g = rgb.g; + clr.b = rgb.b; + clr.opacity = 1; + clr.hex = rgb.hex; + } else { + if (is(clr, "string")) { + clr = Snap.getRGB(clr); + } + if (is(clr, "object") && "r" in clr && "g" in clr && "b" in clr && !("error" in clr)) { + rgb = Snap.rgb2hsl(clr); + clr.h = rgb.h; + clr.s = rgb.s; + clr.l = rgb.l; + rgb = Snap.rgb2hsb(clr); + clr.v = rgb.b; + } else { + clr = {hex: "none"}; + clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1; + clr.error = 1; + } + } + clr.toString = rgbtoString; + return clr; +}; +/*\ + * Snap.hsb2rgb + [ method ] + ** + * Converts HSB values to an RGB object + - h (number) hue + - s (number) saturation + - v (number) value or brightness + = (object) RGB object in the following format: + o { + o r (number) red, + o g (number) green, + o b (number) blue, + o hex (string) color in HTML/CSS format: #•••••• + o } +\*/ +Snap.hsb2rgb = function (h, s, v, o) { + if (is(h, "object") && "h" in h && "s" in h && "b" in h) { + v = h.b; + s = h.s; + h = h.h; + o = h.o; + } + h *= 360; + var R, G, B, X, C; + h = (h % 360) / 60; + C = v * s; + X = C * (1 - abs(h % 2 - 1)); + R = G = B = v - C; + + h = ~~h; + R += [C, X, 0, 0, X, C][h]; + G += [X, C, C, X, 0, 0][h]; + B += [0, 0, X, C, C, X][h]; + return packageRGB(R, G, B, o); +}; +/*\ + * Snap.hsl2rgb + [ method ] + ** + * Converts HSL values to an RGB object + - h (number) hue + - s (number) saturation + - l (number) luminosity + = (object) RGB object in the following format: + o { + o r (number) red, + o g (number) green, + o b (number) blue, + o hex (string) color in HTML/CSS format: #•••••• + o } +\*/ +Snap.hsl2rgb = function (h, s, l, o) { + if (is(h, "object") && "h" in h && "s" in h && "l" in h) { + l = h.l; + s = h.s; + h = h.h; + } + if (h > 1 || s > 1 || l > 1) { + h /= 360; + s /= 100; + l /= 100; + } + h *= 360; + var R, G, B, X, C; + h = (h % 360) / 60; + C = 2 * s * (l < .5 ? l : 1 - l); + X = C * (1 - abs(h % 2 - 1)); + R = G = B = l - C / 2; + + h = ~~h; + R += [C, X, 0, 0, X, C][h]; + G += [X, C, C, X, 0, 0][h]; + B += [0, 0, X, C, C, X][h]; + return packageRGB(R, G, B, o); +}; +/*\ + * Snap.rgb2hsb + [ method ] + ** + * Converts RGB values to an HSB object + - r (number) red + - g (number) green + - b (number) blue + = (object) HSB object in the following format: + o { + o h (number) hue, + o s (number) saturation, + o b (number) brightness + o } +\*/ +Snap.rgb2hsb = function (r, g, b) { + b = prepareRGB(r, g, b); + r = b[0]; + g = b[1]; + b = b[2]; + + var H, S, V, C; + V = mmax(r, g, b); + C = V - mmin(r, g, b); + H = (C == 0 ? null : + V == r ? (g - b) / C : + V == g ? (b - r) / C + 2 : + (r - g) / C + 4 + ); + H = ((H + 360) % 6) * 60 / 360; + S = C == 0 ? 0 : C / V; + return {h: H, s: S, b: V, toString: hsbtoString}; +}; +/*\ + * Snap.rgb2hsl + [ method ] + ** + * Converts RGB values to an HSL object + - r (number) red + - g (number) green + - b (number) blue + = (object) HSL object in the following format: + o { + o h (number) hue, + o s (number) saturation, + o l (number) luminosity + o } +\*/ +Snap.rgb2hsl = function (r, g, b) { + b = prepareRGB(r, g, b); + r = b[0]; + g = b[1]; + b = b[2]; + + var H, S, L, M, m, C; + M = mmax(r, g, b); + m = mmin(r, g, b); + C = M - m; + H = (C == 0 ? null : + M == r ? (g - b) / C : + M == g ? (b - r) / C + 2 : + (r - g) / C + 4); + H = ((H + 360) % 6) * 60 / 360; + L = (M + m) / 2; + S = (C == 0 ? 0 : + L < .5 ? C / (2 * L) : + C / (2 - 2 * L)); + return {h: H, s: S, l: L, toString: hsltoString}; +}; + +// Transformations +// SIERRA Snap.parsePathString(): By _array of arrays,_ I assume you mean a format like this for two separate segments? [ ["M10,10","L90,90"], ["M90,10","L10,90"] ] Otherwise how is each command structured? +/*\ + * Snap.parsePathString + [ method ] + ** + * Utility method + ** + * Parses given path string into an array of arrays of path segments + - pathString (string|array) path string or array of segments (in the last case it is returned straight away) + = (array) array of segments +\*/ +Snap.parsePathString = function (pathString) { + if (!pathString) { + return null; + } + var pth = Snap.path(pathString); + if (pth.arr) { + return Snap.path.clone(pth.arr); + } + + var paramCounts = {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}, + data = []; + if (is(pathString, "array") && is(pathString[0], "array")) { // rough assumption + data = Snap.path.clone(pathString); + } + if (!data.length) { + Str(pathString).replace(pathCommand, function (a, b, c) { + var params = [], + name = b.toLowerCase(); + c.replace(pathValues, function (a, b) { + b && params.push(+b); + }); + if (name == "m" && params.length > 2) { + data.push([b].concat(params.splice(0, 2))); + name = "l"; + b = b == "m" ? "l" : "L"; + } + if (name == "o" && params.length == 1) { + data.push([b, params[0]]); + } + if (name == "r") { + data.push([b].concat(params)); + } else while (params.length >= paramCounts[name]) { + data.push([b].concat(params.splice(0, paramCounts[name]))); + if (!paramCounts[name]) { + break; + } + } + }); + } + data.toString = Snap.path.toString; + pth.arr = Snap.path.clone(data); + return data; +}; +/*\ + * Snap.parseTransformString + [ method ] + ** + * Utility method + ** + * Parses given transform string into an array of transformations + - TString (string|array) transform string or array of transformations (in the last case it is returned straight away) + = (array) array of transformations +\*/ +var parseTransformString = Snap.parseTransformString = function (TString) { + if (!TString) { + return null; + } + var paramCounts = {r: 3, s: 4, t: 2, m: 6}, + data = []; + if (is(TString, "array") && is(TString[0], "array")) { // rough assumption + data = Snap.path.clone(TString); + } + if (!data.length) { + Str(TString).replace(tCommand, function (a, b, c) { + var params = [], + name = b.toLowerCase(); + c.replace(pathValues, function (a, b) { + b && params.push(+b); + }); + data.push([b].concat(params)); + }); + } + data.toString = Snap.path.toString; + return data; +}; +function svgTransform2string(tstr) { + var res = []; + tstr = tstr.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g, function (all, name, params) { + params = params.split(/\s*,\s*|\s+/); + if (name == "rotate" && params.length == 1) { + params.push(0, 0); + } + if (name == "scale") { + if (params.length == 2) { + params.push(0, 0); + } + if (params.length == 1) { + params.push(params[0], 0, 0); + } + } + if (name == "skewX") { + res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]); + } else if (name == "skewY") { + res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]); + } else { + res.push([name.charAt(0)].concat(params)); + } + return all; + }); + return res; +} +Snap._.svgTransform2string = svgTransform2string; +Snap._.rgTransform = new RegExp("^[a-z][" + spaces + "]*-?\\.?\\d", "i"); +function transform2matrix(tstr, bbox) { + var tdata = parseTransformString(tstr), + m = new Matrix; + if (tdata) { + for (var i = 0, ii = tdata.length; i < ii; i++) { + var t = tdata[i], + tlen = t.length, + command = Str(t[0]).toLowerCase(), + absolute = t[0] != command, + inver = absolute ? m.invert() : 0, + x1, + y1, + x2, + y2, + bb; + if (command == "t" && tlen == 2){ + m.translate(t[1], 0); + } else if (command == "t" && tlen == 3) { + if (absolute) { + x1 = inver.x(0, 0); + y1 = inver.y(0, 0); + x2 = inver.x(t[1], t[2]); + y2 = inver.y(t[1], t[2]); + m.translate(x2 - x1, y2 - y1); + } else { + m.translate(t[1], t[2]); + } + } else if (command == "r") { + if (tlen == 2) { + bb = bb || bbox; + m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2); + } else if (tlen == 4) { + if (absolute) { + x2 = inver.x(t[2], t[3]); + y2 = inver.y(t[2], t[3]); + m.rotate(t[1], x2, y2); + } else { + m.rotate(t[1], t[2], t[3]); + } + } + } else if (command == "s") { + if (tlen == 2 || tlen == 3) { + bb = bb || bbox; + m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2); + } else if (tlen == 4) { + if (absolute) { + x2 = inver.x(t[2], t[3]); + y2 = inver.y(t[2], t[3]); + m.scale(t[1], t[1], x2, y2); + } else { + m.scale(t[1], t[1], t[2], t[3]); + } + } else if (tlen == 5) { + if (absolute) { + x2 = inver.x(t[3], t[4]); + y2 = inver.y(t[3], t[4]); + m.scale(t[1], t[2], x2, y2); + } else { + m.scale(t[1], t[2], t[3], t[4]); + } + } + } else if (command == "m" && tlen == 7) { + m.add(t[1], t[2], t[3], t[4], t[5], t[6]); + } + } + } + return m; +} +Snap._.transform2matrix = transform2matrix; +function extractTransform(el, tstr) { + if (tstr == null) { + var doReturn = true; + if (el.type == "linearGradient" || el.type == "radialGradient") { + tstr = el.node.getAttribute("gradientTransform"); + } else if (el.type == "pattern") { + tstr = el.node.getAttribute("patternTransform"); + } else { + tstr = el.node.getAttribute("transform"); + } + if (!tstr) { + return new Matrix; + } + tstr = svgTransform2string(tstr); + } else { + if (!Snap._.rgTransform.test(tstr)) { + tstr = svgTransform2string(tstr); + } else { + tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E); + } + if (is(tstr, "array")) { + tstr = Snap.path ? Snap.path.toString.call(tstr) : Str(tstr); + } + el._.transform = tstr; + } + var m = transform2matrix(tstr, el.getBBox(1)); + if (doReturn) { + return m; + } else { + el.matrix = m; + } +} +Snap._unit2px = unit2px; +var contains = glob.doc.contains || glob.doc.compareDocumentPosition ? + function (a, b) { + var adown = a.nodeType == 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a == bup || !!(bup && bup.nodeType == 1 && ( + adown.contains ? + adown.contains(bup) : + a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16 + )); + } : + function (a, b) { + if (b) { + while (b) { + b = b.parentNode; + if (b == a) { + return true; + } + } + } + return false; + }; +function getSomeDefs(el) { + var cache = Snap._.someDefs; + if (cache && contains(cache.ownerDocument.documentElement, cache)) { + return cache; + } + var p = (el.node.ownerSVGElement && wrap(el.node.ownerSVGElement)) || + (el.node.parentNode && wrap(el.node.parentNode)) || + Snap.select("svg") || + Snap(0, 0), + pdefs = p.select("defs"), + defs = pdefs == null ? false : pdefs.node; + if (!defs) { + defs = make("defs", p.node).node; + } + Snap._.someDefs = defs; + return defs; +} +Snap._.getSomeDefs = getSomeDefs; +function unit2px(el, name, value) { + var defs = getSomeDefs(el), + out = {}, + mgr = defs.querySelector(".svg---mgr"); + if (!mgr) { + mgr = $("rect"); + $(mgr, {width: 10, height: 10, "class": "svg---mgr"}); + defs.appendChild(mgr); + } + function getW(val) { + if (val == null) { + return E; + } + if (val == +val) { + return val; + } + $(mgr, {width: val}); + return mgr.getBBox().width; + } + function getH(val) { + if (val == null) { + return E; + } + if (val == +val) { + return val; + } + $(mgr, {height: val}); + return mgr.getBBox().height; + } + function set(nam, f) { + if (name == null) { + out[nam] = f(el.attr(nam)); + } else if (nam == name) { + out = f(value == null ? el.attr(nam) : value); + } + } + switch (el.type) { + case "rect": + set("rx", getW); + set("ry", getH); + case "image": + set("width", getW); + set("height", getH); + case "text": + set("x", getW); + set("y", getH); + break; + case "circle": + set("cx", getW); + set("cy", getH); + set("r", getW); + break; + case "ellipse": + set("cx", getW); + set("cy", getH); + set("rx", getW); + set("ry", getH); + break; + case "line": + set("x1", getW); + set("x2", getW); + set("y1", getH); + set("y2", getH); + break; + case "marker": + set("refX", getW); + set("markerWidth", getW); + set("refY", getH); + set("markerHeight", getH); + break; + case "radialGradient": + set("fx", getW); + set("fy", getH); + break; + case "tspan": + set("dx", getW); + set("dy", getH); + break; + default: + set(name, getW); + } + return out; +} +/*\ + * Snap.select + [ method ] + ** + * Wraps a DOM element specified by CSS selector as @Element + - query (string) CSS selector of the element + = (Element) the current element +\*/ +Snap.select = function (query) { + return wrap(glob.doc.querySelector(query)); +}; +/*\ + * Snap.selectAll + [ method ] + ** + * Wraps DOM elements specified by CSS selector as set or array of @Element + - query (string) CSS selector of the element + = (Element) the current element +\*/ +Snap.selectAll = function (query) { + var nodelist = glob.doc.querySelectorAll(query), + set = (Snap.set || Array)(); + for (var i = 0; i < nodelist.length; i++) { + set.push(wrap(nodelist[i])); + } + return set; +}; + +function add2group(list) { + if (!is(list, "array")) { + list = Array.prototype.slice.call(arguments, 0); + } + var i = 0, + j = 0, + node = this.node; + while (this[i]) delete this[i++]; + for (i = 0; i < list.length; i++) { + if (list[i].type == "set") { + list[i].forEach(function (el) { + node.appendChild(el.node); + }); + } else { + node.appendChild(list[i].node); + } + } + var children = node.childNodes; + for (i = 0; i < children.length; i++) { + this[j++] = wrap(children[i]); + } + return this; +} +function Element(el) { + if (el.snap in hub) { + return hub[el.snap]; + } + var id = this.id = ID(), + svg; + try { + svg = el.ownerSVGElement; + } catch(e) {} + this.node = el; + if (svg) { + this.paper = new Paper(svg); + } + this.type = el.tagName; + this.anims = {}; + this._ = { + transform: [] + }; + el.snap = id; + hub[id] = this; + if (this.type == "g") { + this.add = add2group; + for (var method in Paper.prototype) if (Paper.prototype[has](method)) { + this[method] = Paper.prototype[method]; + } + } +} +function arrayFirstValue(arr) { + var res; + for (var i = 0, ii = arr.length; i < ii; i++) { + res = res || arr[i]; + if (res) { + return res; + } + } +} +(function (elproto) { + /*\ + * Element.attr + [ method ] + ** + * Gets or sets given attributes of the element + ** + - params (object) contains key-value pairs of attributes you want to set + * or + - param (string) name of the attribute + = (Element) the current element + * or + = (string) value of attribute + > Usage + | el.attr({ + | fill: "#fc0", + | stroke: "#000", + | strokeWidth: 2, // CamelCase... + | "fill-opacity": 0.5 // or dash-separated names + | }); + | console.log(el.attr("fill")); // #fc0 + \*/ + elproto.attr = function (params, value) { + var el = this, + node = el.node; + if (!params) { + return el; + } + if (is(params, "string")) { + if (arguments.length > 1) { + var json = {}; + json[params] = value; + params = json; + } else { + return arrayFirstValue(eve("snap.util.getattr."+params, el)); + } + } + for (var att in params) { + if (params[has](att)) { + eve("snap.util.attr." + att, el, params[att]); + } + } + 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 ] + ** + * Returns the bounding box descriptor for the given element + ** + = (object) bounding box descriptor: + o { + o cx: (number) x of the center, + o cy: (number) x of the center, + o h: (number) height, + o height: (number) height, + o path: (string) path command for the box, + o r0: (number) radius of a circle that fully encloses the box, + o r1: (number) radius of the smallest circle that can be enclosed, + o r2: (number) radius of the largest circle that can be enclosed, + o vb: (string) box as a viewbox command, + o w: (number) width, + o width: (number) width, + o x2: (number) x of the right side, + o x: (number) x of the left side, + o y2: (number) y of the bottom edge, + o y: (number) y of the top edge + o } + \*/ + elproto.getBBox = function (isWithoutTransform) { + var el = this; + if (el.type == "use") { + el = el.original; + } + if (el.removed) { + return {}; + } + var _ = el._; + if (isWithoutTransform) { + _.bboxwt = Snap.path.get[el.type] ? Snap.path.getBBox(el.realPath = Snap.path.get[el.type](el)) : Snap._.box(el.node.getBBox()); + return Snap._.box(_.bboxwt); + } else { + el.realPath = (Snap.path.get[el.type] || Snap.path.get.deflt)(el); + _.bbox = Snap.path.getBBox(Snap.path.map(el.realPath, el.matrix)); + } + return Snap._.box(_.bbox); + }; + var propString = function () { + return this.string; + }; +// SIERRA Element.transform(): seems to allow two return values, one of which (_Element_) is undefined. +// SIERRA Element.transform(): if this only accepts one argument, it's unclear how it can both _get_ and _set_ a transform. +// SIERRA Element.transform(): Unclear how Snap transform string format differs from SVG's. + /*\ + * Element.transform + [ method ] + ** + * Gets or sets transformation of the element + ** + - tstr (string) transform string in Snap or SVG format + = (Element) the current element + * or + = (object) transformation descriptor: + o { + o string (string) transform string, + o globalMatrix (Matrix) matrix of all transformations applied to element or its parents, + o localMatrix (Matrix) matrix of transformations applied only to the element, + o diffMatrix (Matrix) matrix of difference between global and local transformations, + o global (string) global transformation as string, + o local (string) local transformation as string, + o toString (function) returns `string` property + o } + \*/ + elproto.transform = function (tstr) { + var _ = this._; + if (tstr == null) { + var global = new Matrix(this.node.getCTM()), + local = extractTransform(this), + localString = local.toTransformString(), + string = Str(local) == Str(this.matrix) ? + _.transform : localString; + return { + string: string, + globalMatrix: global, + localMatrix: local, + diffMatrix: global.clone().add(local.invert()), + global: global.toTransformString(), + local: localString, + toString: propString + }; + } + if (tstr instanceof Matrix) { + // may be need to apply it directly + // TODO: investigate + tstr = tstr.toTransformString(); + } + extractTransform(this, tstr); + + if (this.node) { + if (this.type == "linearGradient" || this.type == "radialGradient") { + $(this.node, {gradientTransform: this.matrix}); + } else if (this.type == "pattern") { + $(this.node, {patternTransform: this.matrix}); + } else { + $(this.node, {transform: this.matrix}); + } + } + + return this; + }; + /*\ + * Element.parent + [ method ] + ** + * Returns the element's parent + ** + = (Element) the parent element + \*/ + elproto.parent = function () { + return wrap(this.node.parentNode); + }; + /*\ + * Element.append + [ method ] + ** + * Appends the given element to current one + ** + - el (Element|Set) element to append + = (Element) the parent element + \*/ + /*\ + * Element.add + [ method ] + ** + * See @Element.append + \*/ + elproto.append = elproto.add = function (el) { + if (el) { + if (el.type == "set") { + var it = this; + el.forEach(function (el) { + it.add(el); + }); + return this; + } + el = wrap(el); + this.node.appendChild(el.node); + el.paper = this.paper; + } + return this; + }; + /*\ + * Element.appendTo + [ method ] + ** + * Appends the current element to the given one + ** + - el (Element) parent element to append to + = (Element) the child element + \*/ + elproto.appendTo = function (el) { + if (el) { + el = wrap(el); + el.append(this); + } + return this; + }; + /*\ + * Element.prepend + [ method ] + ** + * Prepends the given element to the current one + ** + - el (Element) element to prepend + = (Element) the parent element + \*/ + elproto.prepend = function (el) { + if (el) { + el = wrap(el); + var parent = el.parent(); + this.node.insertBefore(el.node, this.node.firstChild); + this.add && this.add(); + el.paper = this.paper; + this.parent() && this.parent().add(); + parent && parent.add(); + } + return this; + }; + /*\ + * Element.prependTo + [ method ] + ** + * Prepends the current element to the given one + ** + - el (Element) parent element to prepend to + = (Element) the child element + \*/ + elproto.prependTo = function (el) { + el = wrap(el); + el.prepend(this); + return this; + }; + /*\ + * Element.before + [ method ] + ** + * Inserts given element before the current one + ** + - el (Element) element to insert + = (Element) the parent element + \*/ + elproto.before = function (el) { + if (el.type == "set") { + var it = this; + el.forEach(function (el) { + var parent = el.parent(); + it.node.parentNode.insertBefore(el.node, it.node); + parent && parent.add(); + }); + this.parent().add(); + return this; + } + el = wrap(el); + var parent = el.parent(); + this.node.parentNode.insertBefore(el.node, this.node); + this.parent() && this.parent().add(); + parent && parent.add(); + el.paper = this.paper; + return this; + }; + /*\ + * Element.after + [ method ] + ** + * Inserts given element after the current one + ** + - el (Element) element to insert + = (Element) the parent element + \*/ + elproto.after = function (el) { + el = wrap(el); + var parent = el.parent(); + if (this.node.nextSibling) { + this.node.parentNode.insertBefore(el.node, this.node.nextSibling); + } else { + this.node.parentNode.appendChild(el.node); + } + this.parent() && this.parent().add(); + parent && parent.add(); + el.paper = this.paper; + return this; + }; + /*\ + * Element.insertBefore + [ method ] + ** + * Inserts the element after the given one + ** + - el (Element) element next to whom insert to + = (Element) the parent element + \*/ + elproto.insertBefore = function (el) { + el = wrap(el); + var parent = this.parent(); + el.node.parentNode.insertBefore(this.node, el.node); + this.paper = el.paper; + parent && parent.add(); + el.parent() && el.parent().add(); + return this; + }; + /*\ + * Element.insertAfter + [ method ] + ** + * Inserts the element after the given one + ** + - el (Element) element next to whom insert to + = (Element) the parent element + \*/ + elproto.insertAfter = function (el) { + el = wrap(el); + var parent = this.parent(); + el.node.parentNode.insertBefore(this.node, el.node.nextSibling); + this.paper = el.paper; + parent && parent.add(); + el.parent() && el.parent().add(); + return this; + }; + /*\ + * Element.remove + [ method ] + ** + * Removes element from the DOM + = (Element) the detached element + \*/ + elproto.remove = function () { + var parent = this.parent(); + this.node.parentNode && this.node.parentNode.removeChild(this.node); + delete this.paper; + this.removed = true; + parent && parent.add(); + return this; + }; + /*\ + * Element.select + [ method ] + ** + * Gathers the nested @Element matching the given set of CSS selectors + ** + - query (string) CSS selector + = (Element) result of query selection + \*/ + elproto.select = function (query) { + return wrap(this.node.querySelector(query)); + }; + /*\ + * Element.selectAll + [ method ] + ** + * Gathers nested @Element objects matching the given set of CSS selectors + ** + - query (string) CSS selector + = (Set|array) result of query selection + \*/ + elproto.selectAll = function (query) { + var nodelist = this.node.querySelectorAll(query), + set = (Snap.set || Array)(); + for (var i = 0; i < nodelist.length; i++) { + set.push(wrap(nodelist[i])); + } + return set; + }; + /*\ + * Element.asPX + [ method ] + ** + * Returns given attribute of the element as a `px` value (not %, em, etc.) + ** + - attr (string) attribute name + - value (string) #optional attribute value + = (Element) result of query selection + \*/ + elproto.asPX = function (attr, value) { + if (value == null) { + value = this.attr(attr); + } + return +unit2px(this, attr, value); + }; + // SIERRA Element.use(): I suggest adding a note about how to access the original element the returned instantiates. It's a part of SVG with which ordinary web developers may be least familiar. + /*\ + * Element.use + [ method ] + ** + * Creates a `` element linked to the current element + ** + = (Element) the `` element + \*/ + elproto.use = function () { + var use, + id = this.node.id; + if (!id) { + id = this.id; + $(this.node, { + id: id + }); + } + if (this.type == "linearGradient" || this.type == "radialGradient" || + this.type == "pattern") { + use = make(this.type, this.node.parentNode); + } else { + use = make("use", this.node.parentNode); + } + $(use.node, { + "xlink:href": "#" + id + }); + use.original = this; + return use; + }; + /*\ + * Element.clone + [ method ] + ** + * Creates a clone of the element and inserts it after the element + ** + = (Element) the clone + \*/ + function fixids(el) { + var els = el.selectAll("*"), + it, + url = /^\s*url\(("|'|)(.*)\1\)\s*$/, + ids = [], + uses = {}; + function urltest(it, name) { + var val = $(it.node, name); + val = val && val.match(url); + val = val && val[2]; + if (val && val.charAt() == "#") { + val = val.substring(1); + } else { + return; + } + if (val) { + uses[val] = (uses[val] || []).concat(function (id) { + var attr = {}; + attr[name] = URL(id); + $(it.node, attr); + }); + } + } + function linktest(it) { + var val = $(it.node, "xlink:href"); + if (val && val.charAt() == "#") { + val = val.substring(1); + } else { + return; + } + if (val) { + uses[val] = (uses[val] || []).concat(function (id) { + it.attr("xlink:href", "#" + id); + }); + } + } + for (var i = 0, ii = els.length; i < ii; i++) { + it = els[i]; + urltest(it, "fill"); + urltest(it, "stroke"); + urltest(it, "filter"); + urltest(it, "mask"); + urltest(it, "clip-path"); + linktest(it); + var oldid = $(it.node, "id"); + if (oldid) { + $(it.node, {id: it.id}); + ids.push({ + old: oldid, + id: it.id + }); + } + } + for (i = 0, ii = ids.length; i < ii; i++) { + var fs = uses[ids[i].old]; + if (fs) { + for (var j = 0, jj = fs.length; j < jj; j++) { + fs[j](ids[i].id); + } + } + } + } + elproto.clone = function () { + var clone = wrap(this.node.cloneNode(true)); + if ($(clone.node, "id")) { + $(clone.node, {id: clone.id}); + } + fixids(clone); + clone.insertAfter(this); + return clone; + }; +// SIERRA Element.toDefs(): If this _moves_ an element to the region, why is the return value a _clone_? Also unclear why it's called the _relative_ section. Perhaps _shared_? + /*\ + * Element.toDefs + [ method ] + ** + * Moves element to the shared `` area + ** + = (Element) the clone + \*/ + elproto.toDefs = function () { + var defs = getSomeDefs(this); + defs.appendChild(this.node); + return this; + }; +// SIERRA Element.pattern(): x/y/width/height data types are listed as both String and Number. Is that an error, or does it mean strings are coerced? +// SIERRA Element.pattern(): clarify that x/y are offsets that e.g., may add gutters between the tiles. + /*\ + * Element.pattern + [ method ] + ** + * Creates a `` element from the current element + ** + * To create a pattern you have to specify the pattern rect: + - x (string|number) + - y (string|number) + - width (string|number) + - height (string|number) + = (Element) the `` element + * You can use pattern later on as an argument for `fill` attribute: + | var p = paper.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({ + | fill: "none", + | stroke: "#bada55", + | strokeWidth: 5 + | }).pattern(0, 0, 10, 10), + | c = paper.circle(200, 200, 100); + | c.attr({ + | fill: p + | }); + \*/ + elproto.pattern = function (x, y, width, height) { + var p = make("pattern", getSomeDefs(this)); + if (x == null) { + x = this.getBBox(); + } + if (is(x, "object") && "x" in x) { + y = x.y; + width = x.width; + height = x.height; + x = x.x; + } + $(p.node, { + x: x, + y: y, + width: width, + height: height, + patternUnits: "userSpaceOnUse", + id: p.id, + viewBox: [x, y, width, height].join(" ") + }); + p.node.appendChild(this.node); + return p; + }; +// SIERRA Element.marker(): clarify what a reference point is. E.g., helps you offset the object from its edge such as when centering it over a path. +// SIERRA Element.marker(): I suggest the method should accept default reference point values. Perhaps centered with (refX = width/2) and (refY = height/2)? Also, couldn't it assume the element's current _width_ and _height_? And please specify what _x_ and _y_ mean: offsets? If so, from where? Couldn't they also be assigned default values? + /*\ + * Element.marker + [ method ] + ** + * Creates a `` element from the current element + ** + * To create a marker you have to specify the bounding rect and reference point: + - x (number) + - y (number) + - width (number) + - height (number) + - refX (number) + - refY (number) + = (Element) the `` element + * You can specify the marker later as an argument for `marker-start`, `marker-end`, `marker-mid`, and `marker` attributes. The `marker` attribute places the marker at every point along the path, and `marker-mid` places them at every point except the start and end. + \*/ + // TODO add usage for markers + elproto.marker = function (x, y, width, height, refX, refY) { + var p = make("marker", getSomeDefs(this)); + if (x == null) { + x = this.getBBox(); + } + if (is(x, "object") && "x" in x) { + y = x.y; + width = x.width; + height = x.height; + refX = x.refX || x.cx; + refY = x.refY || x.cy; + x = x.x; + } + $(p.node, { + viewBox: [x, y, width, height].join(S), + markerWidth: width, + markerHeight: height, + orient: "auto", + refX: refX || 0, + refY: refY || 0, + id: p.id + }); + p.node.appendChild(this.node); + return p; + }; + // animation + function slice(from, to, f) { + return function (arr) { + var res = arr.slice(from, to); + if (res.length == 1) { + res = res[0]; + } + return f ? f(res) : res; + }; + } + var Animation = function (attr, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + this.attr = attr; + this.dur = ms; + easing && (this.easing = easing); + callback && (this.callback = callback); + }; + // SIERRA All object methods should feature sample code. This is just one instance. + /*\ + * Snap.animation + [ method ] + ** + * Creates an animation object + ** + - attr (object) attributes of final destination + - duration (number) duration of the animation, in milliseconds + - easing (function) #optional one of easing functions of @mina or custom one + - callback (function) #optional callback function that fires when animation ends + = (object) animation object + \*/ + Snap.animation = function (attr, ms, easing, callback) { + return new Animation(attr, ms, easing, callback); + }; + /*\ + * Element.inAnim + [ method ] + ** + * Returns a set of animations that may be able to manipulate the current element + ** + = (object) in format: + o { + o anim (object) animation object, + o curStatus (number) 0..1 — status of the animation: 0 — just started, 1 — just finished, + o status (function) gets or sets the status of the animation, + o stop (function) stops the animation + o } + \*/ + elproto.inAnim = function () { + var el = this, + res = []; + for (var id in el.anims) if (el.anims[has](id)) { + (function (a) { + res.push({ + anim: new Animation(a._attrs, a.dur, a.easing, a._callback), + curStatus: a.status(), + status: function (val) { + return a.status(val); + }, + stop: function () { + a.stop(); + } + }); + }(el.anims[id])); + } + return res; + }; + /*\ + * Snap.animate + [ method ] + ** + * Runs generic animation of one number into another with a caring function + ** + - from (number|array) number or array of numbers + - to (number|array) number or array of numbers + - setter (function) caring function that accepts one number argument + - duration (number) duration, in milliseconds + - easing (function) #optional easing function from @mina or custom + - callback (function) #optional callback function to execute when animation ends + = (object) animation object in @mina format + o { + o id (string) animation id, consider it read-only, + o duration (function) gets or sets the duration of the animation, + o easing (function) easing, + o speed (function) gets or sets the speed of the animation, + o status (function) gets or sets the status of the animation, + o stop (function) stops the animation + o } + | var rect = Snap().rect(0, 0, 10, 10); + | Snap.animate(0, 10, function (val) { + | rect.attr({ + | x: val + | }); + | }, 1000); + | // in given context is equivalent to + | rect.animate({x: 10}, 1000); + \*/ + Snap.animate = function (from, to, setter, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + var now = mina.time(), + anim = mina(from, to, now, now + ms, mina.time, setter, easing); + callback && eve.once("mina.finish." + anim.id, callback); + return anim; + }; + /*\ + * Element.stop + [ method ] + ** + * Stops all the animations for the current element + ** + = (Element) the current element + \*/ + elproto.stop = function () { + var anims = this.inAnim(); + for (var i = 0, ii = anims.length; i < ii; i++) { + anims[i].stop(); + } + return this; + }; + // SIERRA Element.animate(): For _attrs_, clarify if they represent the destination values, and if the animation executes relative to the element's current attribute values. + // SIERRA would a _custom_ animation function be an SVG keySplines value? + /*\ + * Element.animate + [ method ] + ** + * Animates the given attributes of the element + ** + - attrs (object) key-value pairs of destination attributes + - duration (number) duration of the animation in milliseconds + - easing (function) #optional easing function from @mina or custom + - callback (function) #optional callback function that executes when the animation ends + = (Element) the current element + \*/ + elproto.animate = function (attrs, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + if (attrs instanceof Animation) { + callback = attrs.callback; + easing = attrs.easing; + ms = easing.dur; + attrs = attrs.attr; + } + var fkeys = [], tkeys = [], keys = {}, from, to, f, eq, + el = this; + for (var key in attrs) if (attrs[has](key)) { + if (el.equal) { + eq = el.equal(key, Str(attrs[key])); + from = eq.from; + to = eq.to; + f = eq.f; + } else { + from = +el.attr(key); + to = +attrs[key]; + } + var len = is(from, "array") ? from.length : 1; + keys[key] = slice(fkeys.length, fkeys.length + len, f); + fkeys = fkeys.concat(from); + tkeys = tkeys.concat(to); + } + var now = mina.time(), + anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) { + var attr = {}; + for (var key in keys) if (keys[has](key)) { + attr[key] = keys[key](val); + } + el.attr(attr); + }, easing); + el.anims[anim.id] = anim; + anim._attrs = attrs; + anim._callback = callback; + eve.once("mina.finish." + anim.id, function () { + delete el.anims[anim.id]; + callback && callback.call(el); + }); + eve.once("mina.stop." + anim.id, function () { + delete el.anims[anim.id]; + }); + return el; + }; + var eldata = {}; + /*\ + * Element.data + [ method ] + ** + * Adds or retrieves given value associated with given key. (Don’t confuse + * with `data-` attributes) + * + * See also @Element.removeData + - key (string) key to store data + - value (any) #optional value to store + = (object) @Element + * or, if value is not specified: + = (any) value + > Usage + | for (var i = 0, i < 5, i++) { + | paper.circle(10 + 15 * i, 10, 10) + | .attr({fill: "#000"}) + | .data("i", i) + | .click(function () { + | alert(this.data("i")); + | }); + | } + \*/ + elproto.data = function (key, value) { + var data = eldata[this.id] = eldata[this.id] || {}; + if (arguments.length == 0){ + eve("snap.data.get." + this.id, this, data, null); + return data; + } + if (arguments.length == 1) { + if (Snap.is(key, "object")) { + for (var i in key) if (key[has](i)) { + this.data(i, key[i]); + } + return this; + } + eve("snap.data.get." + this.id, this, data[key], key); + return data[key]; + } + data[key] = value; + eve("snap.data.set." + this.id, this, value, key); + return this; + }; + /*\ + * Element.removeData + [ method ] + ** + * Removes value associated with an element by given key. + * If key is not provided, removes all the data of the element. + - key (string) #optional key + = (object) @Element + \*/ + elproto.removeData = function (key) { + if (key == null) { + eldata[this.id] = {}; + } else { + eldata[this.id] && delete eldata[this.id][key]; + } + return this; + }; + /*\ + * Element.outerSVG + [ method ] + ** + * Returns SVG code for the element, equivalent to HTML's `outerHTML`. + * + * See also @Element.innerSVG + = (string) SVG code for the element + \*/ + /*\ + * Element.toString + [ method ] + ** + * See @Element.outerSVG + \*/ + elproto.outerSVG = elproto.toString = toString(1); + /*\ + * Element.innerSVG + [ method ] + ** + * Returns SVG code for the element's contents, equivalent to HTML's `innerHTML` + = (string) SVG code for the element + \*/ + elproto.innerSVG = toString(); + function toString(type) { + return function () { + var res = type ? "<" + this.type : "", + attr = this.node.attributes, + chld = this.node.childNodes; + if (type) { + for (var i = 0, ii = attr.length; i < ii; i++) { + res += " " + attr[i].name + '="' + + attr[i].value.replace(/"/g, '\\"') + '"'; + } + } + if (chld.length) { + type && (res += ">"); + for (i = 0, ii = chld.length; i < ii; i++) { + if (chld[i].nodeType == 3) { + res += chld[i].nodeValue; + } else if (chld[i].nodeType == 1) { + res += wrap(chld[i]).toString(); + } + } + type && (res += ""); + } else { + type && (res += "/>"); + } + return res; + }; + } +}(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 ] + ** + * Parses SVG fragment and converts it into a @Fragment + ** + - svg (string) SVG string + = (Fragment) the @Fragment +\*/ +Snap.parse = function (svg) { + var f = glob.doc.createDocumentFragment(), + full = true, + div = glob.doc.createElement("div"); + svg = Str(svg); + if (!svg.match(/^\s*<\s*svg(?:\s|>)/)) { + svg = "" + svg + ""; + full = false; + } + div.innerHTML = svg; + svg = div.getElementsByTagName("svg")[0]; + if (svg) { + if (full) { + f = svg; + } else { + while (svg.firstChild) { + f.appendChild(svg.firstChild); + } + } + } + div.innerHTML = E; + return new Fragment(f); +}; +function Fragment(frag) { + this.node = frag; +} +/*\ + * Fragment.select + [ method ] + ** + * See @Element.select +\*/ +Fragment.prototype.select = Element.prototype.select; +/*\ + * Fragment.selectAll + [ method ] + ** + * See @Element.selectAll +\*/ +Fragment.prototype.selectAll = Element.prototype.selectAll; +// SIERRA Snap.fragment() could especially use a code example +/*\ + * Snap.fragment + [ method ] + ** + * Creates a DOM fragment from a given list of elements or strings + ** + - varargs (…) SVG string + = (Fragment) the @Fragment +\*/ +Snap.fragment = function () { + var args = Array.prototype.slice.call(arguments, 0), + f = glob.doc.createDocumentFragment(); + for (var i = 0, ii = args.length; i < ii; i++) { + var item = args[i]; + if (item.node && item.node.nodeType) { + f.appendChild(item.node); + } + if (item.nodeType) { + f.appendChild(item); + } + if (typeof item == "string") { + f.appendChild(Snap.parse(item).node); + } + } + return new Fragment(f); +}; + +function make(name, parent) { + var res = $(name); + parent.appendChild(res); + var el = wrap(res); + el.type = name; + return el; +} +function Paper(w, h) { + var res, + desc, + defs, + proto = Paper.prototype; + if (w && w.tagName == "svg") { + if (w.snap in hub) { + return hub[w.snap]; + } + res = new Element(w); + desc = w.getElementsByTagName("desc")[0]; + defs = w.getElementsByTagName("defs")[0]; + if (!desc) { + desc = $("desc"); + desc.appendChild(glob.doc.createTextNode("Created with Snap")); + res.node.appendChild(desc); + } + if (!defs) { + defs = $("defs"); + res.node.appendChild(defs); + } + res.defs = defs; + for (var key in proto) if (proto[has](key)) { + res[key] = proto[key]; + } + res.paper = res.root = res; + } else { + res = make("svg", glob.doc.body); + $(res.node, { + height: h, + version: 1.1, + width: w, + xmlns: xmlns + }); + } + return res; +} +function wrap(dom) { + if (!dom) { + return dom; + } + if (dom instanceof Element || dom instanceof Fragment) { + return dom; + } + if (dom.tagName == "svg") { + return new Paper(dom); + } + 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" in x) { + 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" in cx) { + 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" in cx) { + 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; + }; +// SIERRA Paper.g(): Don't understand the code comment about the order being _different._ Wouldn't it be a rect followed by a circle? + /*\ + * 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); + el.add = add2group; + for (var method in proto) if (proto[has](method)) { + el[method] = proto[method]; + } + 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.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.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])); + } + 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; + } +}; +/*\ + * 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 = 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.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 +var cssAttr = { + "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 +}; + +eve.on("snap.util.attr", function (value) { + var att = eve.nt(), + attr = {}; + att = att.substring(att.lastIndexOf(".") + 1); + attr[att] = value; + var style = att.replace(/-(\w)/gi, function (all, letter) { + return letter.toUpperCase(); + }), + css = att.replace(/[A-Z]/g, function (letter) { + return "-" + letter.toLowerCase(); + }); + if (cssAttr[has](css)) { + this.node.style[style] = value == null ? E : value; + } else { + $(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 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").split(separator); + return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]); + // TODO: investigate why I need to z-index it +})(-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; +}); +// 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 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, + body = doc.body, + docElem = doc.documentElement, + clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, + top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop, + left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft; + return { + y: top, + x: left + }; +}; +/*\ + * Snap.getElementByPoint + [ method ] + ** + * Returns you topmost element under given point. + ** + = (object) Snap element object + - x (number) x coordinate from the top left corner of the window + - y (number) y coordinate from the top left corner of the window + > Usage + | Snap.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"}); +\*/ +Snap.getElementByPoint = function (x, y) { + var paper = this, + svg = paper.canvas, + target = glob.doc.elementFromPoint(x, y); + if (glob.win.opera && target.tagName == "svg") { + var so = getOffset(target), + sr = target.createSVGRect(); + sr.x = x - so.x; + sr.y = y - so.y; + sr.width = sr.height = 1; + var hits = target.getIntersectionList(sr, null); + if (hits.length) { + target = hits[hits.length - 1]; + } + } + if (!target) { + return null; + } + return wrap(target); +}; +/*\ + * Snap.plugin + [ method ] + ** + * Let you write plugins. You pass in a function with four arguments, like this: + | Snap.plugin(function (Snap, Element, Paper, global) { + | Snap.newmethod = function () {}; + | Element.prototype.newmethod = function () {}; + | Paper.prototype.newmethod = function () {}; + | }); + * Inside the function you have access to all main objects (and their + * prototypes). This allow you to extend anything you want. + ** + - f (function) your plugin body +\*/ +Snap.plugin = function (f) { + f(Snap, Element, Paper, glob); +}; +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) { + var elproto = Element.prototype, + is = Snap.is, + clone = Snap._.clone, + has = "hasOwnProperty", + p2s = /,?([a-z]),?/gi, + toFloat = parseFloat, + math = Math, + PI = math.PI, + mmin = math.min, + mmax = math.max, + pow = math.pow, + abs = math.abs; + function paths(ps) { + var p = paths.ps = paths.ps || {}; + if (p[ps]) { + p[ps].sleep = 100; + } else { + p[ps] = { + sleep: 100 + }; + } + setTimeout(function () { + for (var key in p) if (p[has](key) && key != ps) { + p[key].sleep--; + !p[key].sleep && delete p[key]; + } + }); + return p[ps]; + } + function box(x, y, width, height) { + if (x == null) { + x = y = width = height = 0; + } + if (y == null) { + y = x.y; + width = x.width; + height = x.height; + x = x.x; + } + return { + x: x, + y: y, + width: width, + w: width, + height: height, + h: height, + x2: x + width, + y2: y + height, + cx: x + width / 2, + cy: y + height / 2, + r1: math.min(width, height) / 2, + r2: math.max(width, height) / 2, + r0: math.sqrt(width * width + height * height) / 2, + path: rectPath(x, y, width, height), + vb: [x, y, width, height].join(" ") + }; + } + function toString() { + return this.join(",").replace(p2s, "$1"); + } + function pathClone(pathArray) { + var res = clone(pathArray); + res.toString = toString; + return res; + } + function getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) { + if (length == null) { + return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y); + } else { + return findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, + getTotLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length)); + } + } + function getLengthFactory(istotal, subpath) { + function O(val) { + return +(+val).toFixed(3); + } + return Snap._.cacher(function (path, length, onlystart) { + if (path instanceof Element) { + path = path.attr("d"); + } + path = path2curve(path); + var x, y, p, l, sp = "", subpaths = {}, point, + len = 0; + for (var i = 0, ii = path.length; i < ii; i++) { + p = path[i]; + if (p[0] == "M") { + x = +p[1]; + y = +p[2]; + } else { + l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); + if (len + l > length) { + if (subpath && !subpaths.start) { + point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); + sp += [ + "C" + O(point.start.x), + O(point.start.y), + O(point.m.x), + O(point.m.y), + O(point.x), + O(point.y) + ]; + if (onlystart) {return sp;} + subpaths.start = sp; + sp = [ + "M" + O(point.x), + O(point.y) + "C" + O(point.n.x), + O(point.n.y), + O(point.end.x), + O(point.end.y), + O(p[5]), + O(p[6]) + ].join(); + len += l; + x = +p[5]; + y = +p[6]; + continue; + } + if (!istotal && !subpath) { + point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); + return point; + } + } + len += l; + x = +p[5]; + y = +p[6]; + } + sp += p.shift() + p; + } + subpaths.end = sp; + point = istotal ? len : subpath ? subpaths : findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1); + return point; + }, null, Snap._.clone); + } + var getTotalLength = getLengthFactory(1), + getPointAtLength = getLengthFactory(), + getSubpathsAtLength = getLengthFactory(0, 1); + function findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { + var t1 = 1 - t, + t13 = pow(t1, 3), + t12 = pow(t1, 2), + t2 = t * t, + t3 = t2 * t, + x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x, + y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y, + mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x), + my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y), + nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x), + ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y), + ax = t1 * p1x + t * c1x, + ay = t1 * p1y + t * c1y, + cx = t1 * c2x + t * p2x, + cy = t1 * c2y + t * p2y, + alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI); + // (mx > nx || my < ny) && (alpha += 180); + return { + x: x, + y: y, + m: {x: mx, y: my}, + n: {x: nx, y: ny}, + start: {x: ax, y: ay}, + end: {x: cx, y: cy}, + alpha: alpha + }; + } + function bezierBBox(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { + if (!Snap.is(p1x, "array")) { + p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]; + } + var bbox = curveDim.apply(null, p1x); + return box( + bbox.min.x, + bbox.min.y, + bbox.max.x - bbox.min.x, + bbox.max.y - bbox.min.y + ); + } + function isPointInsideBBox(bbox, x, y) { + return x >= bbox.x && + x <= bbox.x + bbox.width && + y >= bbox.y && + y <= bbox.y + bbox.height; + } + function isBBoxIntersect(bbox1, bbox2) { + bbox1 = box(bbox1); + bbox2 = box(bbox2); + return isPointInsideBBox(bbox2, bbox1.x, bbox1.y) + || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y) + || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2) + || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2) + || isPointInsideBBox(bbox1, bbox2.x, bbox2.y) + || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y) + || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2) + || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2) + || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x + || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x) + && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y + || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y); + } + function base3(t, p1, p2, p3, p4) { + var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4, + t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; + return t * t2 - 3 * p1 + 3 * p2; + } + function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) { + if (z == null) { + z = 1; + } + z = z > 1 ? 1 : z < 0 ? 0 : z; + var z2 = z / 2, + n = 12, + Tvalues = [-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816], + Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472], + sum = 0; + for (var i = 0; i < n; i++) { + var ct = z2 * Tvalues[i] + z2, + xbase = base3(ct, x1, x2, x3, x4), + ybase = base3(ct, y1, y2, y3, y4), + comb = xbase * xbase + ybase * ybase; + sum += Cvalues[i] * math.sqrt(comb); + } + return z2 * sum; + } + function getTotLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) { + if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) { + return; + } + var t = 1, + step = t / 2, + t2 = t - step, + l, + e = .01; + l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2); + while (abs(l - ll) > e) { + step /= 2; + t2 += (l < ll ? 1 : -1) * step; + l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2); + } + return t2; + } + function intersect(x1, y1, x2, y2, x3, y3, x4, y4) { + if ( + mmax(x1, x2) < mmin(x3, x4) || + mmin(x1, x2) > mmax(x3, x4) || + mmax(y1, y2) < mmin(y3, y4) || + mmin(y1, y2) > mmax(y3, y4) + ) { + return; + } + var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), + ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), + denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); + + if (!denominator) { + return; + } + var px = nx / denominator, + py = ny / denominator, + px2 = +px.toFixed(2), + py2 = +py.toFixed(2); + if ( + px2 < +mmin(x1, x2).toFixed(2) || + px2 > +mmax(x1, x2).toFixed(2) || + px2 < +mmin(x3, x4).toFixed(2) || + px2 > +mmax(x3, x4).toFixed(2) || + py2 < +mmin(y1, y2).toFixed(2) || + py2 > +mmax(y1, y2).toFixed(2) || + py2 < +mmin(y3, y4).toFixed(2) || + py2 > +mmax(y3, y4).toFixed(2) + ) { + return; + } + return {x: px, y: py}; + } + function inter(bez1, bez2) { + return interHelper(bez1, bez2); + } + function interCount(bez1, bez2) { + return interHelper(bez1, bez2, 1); + } + function interHelper(bez1, bez2, justCount) { + var bbox1 = bezierBBox(bez1), + bbox2 = bezierBBox(bez2); + if (!isBBoxIntersect(bbox1, bbox2)) { + return justCount ? 0 : []; + } + var l1 = bezlen.apply(0, bez1), + l2 = bezlen.apply(0, bez2), + n1 = ~~(l1 / 5), + n2 = ~~(l2 / 5), + dots1 = [], + dots2 = [], + xy = {}, + res = justCount ? 0 : []; + for (var i = 0; i < n1 + 1; i++) { + var p = findDotsAtSegment.apply(0, bez1.concat(i / n1)); + dots1.push({x: p.x, y: p.y, t: i / n1}); + } + for (i = 0; i < n2 + 1; i++) { + p = findDotsAtSegment.apply(0, bez2.concat(i / n2)); + dots2.push({x: p.x, y: p.y, t: i / n2}); + } + for (i = 0; i < n1; i++) { + for (var j = 0; j < n2; j++) { + var di = dots1[i], + di1 = dots1[i + 1], + dj = dots2[j], + dj1 = dots2[j + 1], + ci = abs(di1.x - di.x) < .001 ? "y" : "x", + cj = abs(dj1.x - dj.x) < .001 ? "y" : "x", + is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y); + if (is) { + if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) { + continue; + } + xy[is.x.toFixed(4)] = is.y.toFixed(4); + var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t), + t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t); + if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) { + if (justCount) { + res++; + } else { + res.push({ + x: is.x, + y: is.y, + t1: t1, + t2: t2 + }); + } + } + } + } + } + return res; + } + function pathIntersection(path1, path2) { + return interPathHelper(path1, path2); + } + function pathIntersectionNumber(path1, path2) { + return interPathHelper(path1, path2, 1); + } + function interPathHelper(path1, path2, justCount) { + path1 = path2curve(path1); + path2 = path2curve(path2); + var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2, + res = justCount ? 0 : []; + for (var i = 0, ii = path1.length; i < ii; i++) { + var pi = path1[i]; + if (pi[0] == "M") { + x1 = x1m = pi[1]; + y1 = y1m = pi[2]; + } else { + if (pi[0] == "C") { + bez1 = [x1, y1].concat(pi.slice(1)); + x1 = bez1[6]; + y1 = bez1[7]; + } else { + bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m]; + x1 = x1m; + y1 = y1m; + } + for (var j = 0, jj = path2.length; j < jj; j++) { + var pj = path2[j]; + if (pj[0] == "M") { + x2 = x2m = pj[1]; + y2 = y2m = pj[2]; + } else { + if (pj[0] == "C") { + bez2 = [x2, y2].concat(pj.slice(1)); + x2 = bez2[6]; + y2 = bez2[7]; + } else { + bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m]; + x2 = x2m; + y2 = y2m; + } + var intr = interHelper(bez1, bez2, justCount); + if (justCount) { + res += intr; + } else { + for (var k = 0, kk = intr.length; k < kk; k++) { + intr[k].segment1 = i; + intr[k].segment2 = j; + intr[k].bez1 = bez1; + intr[k].bez2 = bez2; + } + res = res.concat(intr); + } + } + } + } + } + return res; + } + function isPointInsidePath(path, x, y) { + var bbox = pathBBox(path); + return isPointInsideBBox(bbox, x, y) && + interPathHelper(path, [["M", x, y], ["H", bbox.x2 + 10]], 1) % 2 == 1; + } + function pathBBox(path) { + var pth = paths(path); + if (pth.bbox) { + return clone(pth.bbox); + } + if (!path) { + return box(); + } + path = path2curve(path); + var x = 0, + y = 0, + X = [], + Y = [], + p; + for (var i = 0, ii = path.length; i < ii; i++) { + p = path[i]; + if (p[0] == "M") { + x = p[1]; + y = p[2]; + X.push(x); + Y.push(y); + } else { + var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); + X = X.concat(dim.min.x, dim.max.x); + Y = Y.concat(dim.min.y, dim.max.y); + x = p[5]; + y = p[6]; + } + } + var xmin = mmin.apply(0, X), + ymin = mmin.apply(0, Y), + xmax = mmax.apply(0, X), + ymax = mmax.apply(0, Y), + bb = box(xmin, ymin, xmax - xmin, ymax - ymin); + pth.bbox = clone(bb); + return bb; + } + function rectPath(x, y, w, h, r) { + if (r) { + return [ + ["M", x + r, y], + ["l", w - r * 2, 0], + ["a", r, r, 0, 0, 1, r, r], + ["l", 0, h - r * 2], + ["a", r, r, 0, 0, 1, -r, r], + ["l", r * 2 - w, 0], + ["a", r, r, 0, 0, 1, -r, -r], + ["l", 0, r * 2 - h], + ["a", r, r, 0, 0, 1, r, -r], + ["z"] + ]; + } + var res = [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]]; + res.toString = toString; + return res; + } + function ellipsePath(x, y, rx, ry, a) { + if (a == null && ry == null) { + ry = rx; + } + if (a != null) { + var rad = Math.PI / 180, + x1 = x + rx * Math.cos(-ry * rad), + x2 = x + rx * Math.cos(-a * rad), + y1 = y + rx * Math.sin(-ry * rad), + y2 = y + rx * Math.sin(-a * rad), + res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]]; + } else { + res = [ + ["M", x, y], + ["m", 0, -ry], + ["a", rx, ry, 0, 1, 1, 0, 2 * ry], + ["a", rx, ry, 0, 1, 1, 0, -2 * ry], + ["z"] + ]; + } + res.toString = toString; + return res; + } + var unit2px = Snap._unit2px, + getPath = { + path: function (el) { + return el.attr("path"); + }, + circle: function (el) { + var attr = unit2px(el); + return ellipsePath(attr.cx, attr.cy, attr.r); + }, + ellipse: function (el) { + var attr = unit2px(el); + return ellipsePath(attr.cx, attr.cy, attr.rx, attr.ry); + }, + rect: function (el) { + var attr = unit2px(el); + return rectPath(attr.x, attr.y, attr.width, attr.height, attr.rx, attr.ry); + }, + image: function (el) { + var attr = unit2px(el); + return rectPath(attr.x, attr.y, attr.width, attr.height); + }, + text: function (el) { + var bbox = el.node.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, + g: function (el) { + var bbox = el.node.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, + symbol: function (el) { + var bbox = el.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, + line: function (el) { + return "M" + [el.attr("x1"), el.attr("y1"), el.attr("x2"), el.attr("y2")]; + }, + polyline: function (el) { + return "M" + el.attr("points"); + }, + polygon: function (el) { + return "M" + el.attr("points") + "z"; + }, + svg: function (el) { + var bbox = el.node.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, + deflt: function (el) { + var bbox = el.node.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + } + }; + function pathToRelative(pathArray) { + var pth = paths(pathArray), + lowerCase = String.prototype.toLowerCase; + if (pth.rel) { + return pathClone(pth.rel); + } + if (!Snap.is(pathArray, "array") || !Snap.is(pathArray && pathArray[0], "array")) { + pathArray = Snap.parsePathString(pathArray); + } + var res = [], + x = 0, + y = 0, + mx = 0, + my = 0, + start = 0; + if (pathArray[0][0] == "M") { + x = pathArray[0][1]; + y = pathArray[0][2]; + mx = x; + my = y; + start++; + res.push(["M", x, y]); + } + for (var i = start, ii = pathArray.length; i < ii; i++) { + var r = res[i] = [], + pa = pathArray[i]; + if (pa[0] != lowerCase.call(pa[0])) { + r[0] = lowerCase.call(pa[0]); + switch (r[0]) { + case "a": + r[1] = pa[1]; + r[2] = pa[2]; + r[3] = pa[3]; + r[4] = pa[4]; + r[5] = pa[5]; + r[6] = +(pa[6] - x).toFixed(3); + r[7] = +(pa[7] - y).toFixed(3); + break; + case "v": + r[1] = +(pa[1] - y).toFixed(3); + break; + case "m": + mx = pa[1]; + my = pa[2]; + default: + for (var j = 1, jj = pa.length; j < jj; j++) { + r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3); + } + } + } else { + r = res[i] = []; + if (pa[0] == "m") { + mx = pa[1] + x; + my = pa[2] + y; + } + for (var k = 0, kk = pa.length; k < kk; k++) { + res[i][k] = pa[k]; + } + } + var len = res[i].length; + switch (res[i][0]) { + case "z": + x = mx; + y = my; + break; + case "h": + x += +res[i][len - 1]; + break; + case "v": + y += +res[i][len - 1]; + break; + default: + x += +res[i][len - 2]; + y += +res[i][len - 1]; + } + } + res.toString = toString; + pth.rel = pathClone(res); + return res; + } + function pathToAbsolute(pathArray) { + var pth = paths(pathArray); + if (pth.abs) { + return pathClone(pth.abs); + } + if (!is(pathArray, "array") || !is(pathArray && pathArray[0], "array")) { // rough assumption + pathArray = Snap.parsePathString(pathArray); + } + if (!pathArray || !pathArray.length) { + return [["M", 0, 0]]; + } + var res = [], + x = 0, + y = 0, + mx = 0, + my = 0, + start = 0, + pa0; + if (pathArray[0][0] == "M") { + x = +pathArray[0][1]; + y = +pathArray[0][2]; + mx = x; + my = y; + start++; + res[0] = ["M", x, y]; + } + var crz = pathArray.length == 3 && + pathArray[0][0] == "M" && + pathArray[1][0].toUpperCase() == "R" && + pathArray[2][0].toUpperCase() == "Z"; + for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) { + res.push(r = []); + pa = pathArray[i]; + pa0 = pa[0]; + if (pa0 != pa0.toUpperCase()) { + r[0] = pa0.toUpperCase(); + switch (r[0]) { + case "A": + r[1] = pa[1]; + r[2] = pa[2]; + r[3] = pa[3]; + r[4] = pa[4]; + r[5] = pa[5]; + r[6] = +(pa[6] + x); + r[7] = +(pa[7] + y); + break; + case "V": + r[1] = +pa[1] + y; + break; + case "H": + r[1] = +pa[1] + x; + break; + case "R": + var dots = [x, y].concat(pa.slice(1)); + for (var j = 2, jj = dots.length; j < jj; j++) { + dots[j] = +dots[j] + x; + dots[++j] = +dots[j] + y; + } + res.pop(); + res = res.concat(catmullRom2bezier(dots, crz)); + break; + case "O": + res.pop(); + dots = ellipsePath(x, y, pa[1], pa[2]); + dots.push(dots[0]); + res = res.concat(dots); + break; + case "U": + res.pop(); + res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3])); + r = ["U"].concat(res[res.length - 1].slice(-2)); + break; + case "M": + mx = +pa[1] + x; + my = +pa[2] + y; + default: + for (j = 1, jj = pa.length; j < jj; j++) { + r[j] = +pa[j] + ((j % 2) ? x : y); + } + } + } else if (pa0 == "R") { + dots = [x, y].concat(pa.slice(1)); + res.pop(); + res = res.concat(catmullRom2bezier(dots, crz)); + r = ["R"].concat(pa.slice(-2)); + } else if (pa0 == "O") { + res.pop(); + dots = ellipsePath(x, y, pa[1], pa[2]); + dots.push(dots[0]); + res = res.concat(dots); + } else if (pa0 == "U") { + res.pop(); + res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3])); + r = ["U"].concat(res[res.length - 1].slice(-2)); + } else { + for (var k = 0, kk = pa.length; k < kk; k++) { + r[k] = pa[k]; + } + } + pa0 = pa0.toUpperCase(); + if (pa0 != "O") { + switch (r[0]) { + case "Z": + x = mx; + y = my; + break; + case "H": + x = r[1]; + break; + case "V": + y = r[1]; + break; + case "M": + mx = r[r.length - 2]; + my = r[r.length - 1]; + default: + x = r[r.length - 2]; + y = r[r.length - 1]; + } + } + } + res.toString = toString; + pth.abs = pathClone(res); + return res; + } + function l2c(x1, y1, x2, y2) { + return [x1, y1, x2, y2, x2, y2]; + } + function q2c(x1, y1, ax, ay, x2, y2) { + var _13 = 1 / 3, + _23 = 2 / 3; + return [ + _13 * x1 + _23 * ax, + _13 * y1 + _23 * ay, + _13 * x2 + _23 * ax, + _13 * y2 + _23 * ay, + x2, + y2 + ]; + } + function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { + // for more information of where this math came from visit: + // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes + var _120 = PI * 120 / 180, + rad = PI / 180 * (+angle || 0), + res = [], + xy, + rotate = Snap._.cacher(function (x, y, rad) { + var X = x * math.cos(rad) - y * math.sin(rad), + Y = x * math.sin(rad) + y * math.cos(rad); + return {x: X, y: Y}; + }); + if (!recursive) { + xy = rotate(x1, y1, -rad); + x1 = xy.x; + y1 = xy.y; + xy = rotate(x2, y2, -rad); + x2 = xy.x; + y2 = xy.y; + var cos = math.cos(PI / 180 * angle), + sin = math.sin(PI / 180 * angle), + x = (x1 - x2) / 2, + y = (y1 - y2) / 2; + var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); + if (h > 1) { + h = math.sqrt(h); + rx = h * rx; + ry = h * ry; + } + var rx2 = rx * rx, + ry2 = ry * ry, + k = (large_arc_flag == sweep_flag ? -1 : 1) * + math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))), + cx = k * rx * y / ry + (x1 + x2) / 2, + cy = k * -ry * x / rx + (y1 + y2) / 2, + f1 = math.asin(((y1 - cy) / ry).toFixed(9)), + f2 = math.asin(((y2 - cy) / ry).toFixed(9)); + + f1 = x1 < cx ? PI - f1 : f1; + f2 = x2 < cx ? PI - f2 : f2; + f1 < 0 && (f1 = PI * 2 + f1); + f2 < 0 && (f2 = PI * 2 + f2); + if (sweep_flag && f1 > f2) { + f1 = f1 - PI * 2; + } + if (!sweep_flag && f2 > f1) { + f2 = f2 - PI * 2; + } + } else { + f1 = recursive[0]; + f2 = recursive[1]; + cx = recursive[2]; + cy = recursive[3]; + } + var df = f2 - f1; + if (abs(df) > _120) { + var f2old = f2, + x2old = x2, + y2old = y2; + f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); + x2 = cx + rx * math.cos(f2); + y2 = cy + ry * math.sin(f2); + res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); + } + df = f2 - f1; + var c1 = math.cos(f1), + s1 = math.sin(f1), + c2 = math.cos(f2), + s2 = math.sin(f2), + t = math.tan(df / 4), + hx = 4 / 3 * rx * t, + hy = 4 / 3 * ry * t, + m1 = [x1, y1], + m2 = [x1 + hx * s1, y1 - hy * c1], + m3 = [x2 + hx * s2, y2 - hy * c2], + m4 = [x2, y2]; + m2[0] = 2 * m1[0] - m2[0]; + m2[1] = 2 * m1[1] - m2[1]; + if (recursive) { + return [m2, m3, m4].concat(res); + } else { + res = [m2, m3, m4].concat(res).join().split(","); + var newres = []; + for (var i = 0, ii = res.length; i < ii; i++) { + newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; + } + return newres; + } + } + function findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { + var t1 = 1 - t; + return { + x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x, + y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y + }; + } + function curveDim(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { + var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x), + b = 2 * (c1x - p1x) - 2 * (c2x - c1x), + c = p1x - c1x, + t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a, + t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a, + y = [p1y, p2y], + x = [p1x, p2x], + dot; + abs(t1) > "1e12" && (t1 = .5); + abs(t2) > "1e12" && (t2 = .5); + if (t1 > 0 && t1 < 1) { + dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); + x.push(dot.x); + y.push(dot.y); + } + if (t2 > 0 && t2 < 1) { + dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); + x.push(dot.x); + y.push(dot.y); + } + a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y); + b = 2 * (c1y - p1y) - 2 * (c2y - c1y); + c = p1y - c1y; + t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a; + t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a; + abs(t1) > "1e12" && (t1 = .5); + abs(t2) > "1e12" && (t2 = .5); + if (t1 > 0 && t1 < 1) { + dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); + x.push(dot.x); + y.push(dot.y); + } + if (t2 > 0 && t2 < 1) { + dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); + x.push(dot.x); + y.push(dot.y); + } + return { + min: {x: mmin.apply(0, x), y: mmin.apply(0, y)}, + max: {x: mmax.apply(0, x), y: mmax.apply(0, y)} + }; + } + function path2curve(path, path2) { + var pth = !path2 && paths(path); + if (!path2 && pth.curve) { + return pathClone(pth.curve); + } + var p = pathToAbsolute(path), + p2 = path2 && pathToAbsolute(path2), + attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, + attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, + processPath = function (path, d) { + var nx, ny; + if (!path) { + return ["C", d.x, d.y, d.x, d.y, d.x, d.y]; + } + !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null); + switch (path[0]) { + case "M": + d.X = path[1]; + d.Y = path[2]; + break; + case "A": + path = ["C"].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1)))); + break; + case "S": + nx = d.x + (d.x - (d.bx || d.x)); + ny = d.y + (d.y - (d.by || d.y)); + path = ["C", nx, ny].concat(path.slice(1)); + break; + case "T": + d.qx = d.x + (d.x - (d.qx || d.x)); + d.qy = d.y + (d.y - (d.qy || d.y)); + path = ["C"].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])); + break; + case "Q": + d.qx = path[1]; + d.qy = path[2]; + path = ["C"].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4])); + break; + case "L": + path = ["C"].concat(l2c(d.x, d.y, path[1], path[2])); + break; + case "H": + path = ["C"].concat(l2c(d.x, d.y, path[1], d.y)); + break; + case "V": + path = ["C"].concat(l2c(d.x, d.y, d.x, path[1])); + break; + case "Z": + path = ["C"].concat(l2c(d.x, d.y, d.X, d.Y)); + break; + } + return path; + }, + fixArc = function (pp, i) { + if (pp[i].length > 7) { + pp[i].shift(); + var pi = pp[i]; + while (pi.length) { + pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6))); + } + pp.splice(i, 1); + ii = mmax(p.length, p2 && p2.length || 0); + } + }, + fixM = function (path1, path2, a1, a2, i) { + if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") { + path2.splice(i, 0, ["M", a2.x, a2.y]); + a1.bx = 0; + a1.by = 0; + a1.x = path1[i][1]; + a1.y = path1[i][2]; + ii = mmax(p.length, p2 && p2.length || 0); + } + }; + for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) { + p[i] = processPath(p[i], attrs); + fixArc(p, i); + p2 && (p2[i] = processPath(p2[i], attrs2)); + p2 && fixArc(p2, i); + fixM(p, p2, attrs, attrs2, i); + fixM(p2, p, attrs2, attrs, i); + var seg = p[i], + seg2 = p2 && p2[i], + seglen = seg.length, + seg2len = p2 && seg2.length; + attrs.x = seg[seglen - 2]; + attrs.y = seg[seglen - 1]; + attrs.bx = toFloat(seg[seglen - 4]) || attrs.x; + attrs.by = toFloat(seg[seglen - 3]) || attrs.y; + attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x); + attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y); + attrs2.x = p2 && seg2[seg2len - 2]; + attrs2.y = p2 && seg2[seg2len - 1]; + } + if (!p2) { + pth.curve = pathClone(p); + } + return p2 ? [p, p2] : p; + } + function mapPath(path, matrix) { + if (!matrix) { + return path; + } + var x, y, i, j, ii, jj, pathi; + path = path2curve(path); + for (i = 0, ii = path.length; i < ii; i++) { + pathi = path[i]; + for (j = 1, jj = pathi.length; j < jj; j += 2) { + x = matrix.x(pathi[j], pathi[j + 1]); + y = matrix.y(pathi[j], pathi[j + 1]); + pathi[j] = x; + pathi[j + 1] = y; + } + } + return path; + } + + // http://schepers.cc/getting-to-the-point + function catmullRom2bezier(crp, z) { + var d = []; + for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { + var p = [ + {x: +crp[i - 2], y: +crp[i - 1]}, + {x: +crp[i], y: +crp[i + 1]}, + {x: +crp[i + 2], y: +crp[i + 3]}, + {x: +crp[i + 4], y: +crp[i + 5]} + ]; + if (z) { + if (!i) { + p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]}; + } else if (iLen - 4 == i) { + p[3] = {x: +crp[0], y: +crp[1]}; + } else if (iLen - 2 == i) { + p[2] = {x: +crp[0], y: +crp[1]}; + p[3] = {x: +crp[2], y: +crp[3]}; + } + } else { + if (iLen - 4 == i) { + p[3] = p[2]; + } else if (!i) { + p[0] = {x: +crp[i], y: +crp[i + 1]}; + } + } + d.push(["C", + (-p[0].x + 6 * p[1].x + p[2].x) / 6, + (-p[0].y + 6 * p[1].y + p[2].y) / 6, + (p[1].x + 6 * p[2].x - p[3].x) / 6, + (p[1].y + 6*p[2].y - p[3].y) / 6, + p[2].x, + p[2].y + ]); + } + + return d; + } + + // export + Snap.path = paths; + + /*\ + * Snap.path.getTotalLength + [ method ] + ** + * Returns the length of the given path in pixels + ** + - path (string) SVG path string + ** + = (number) length + \*/ + Snap.path.getTotalLength = getTotalLength; + /*\ + * Snap.path.getPointAtLength + [ method ] + ** + * Returns the coordinates of the point located at the given length along the given path + ** + - path (string) SVG path string + - length (number) length, in pixels, from the start of the path, excluding non-rendering jumps + ** + = (object) representation of the point: + o { + o x: (number) x coordinate, + o y: (number) y coordinate, + o alpha: (number) angle of derivative + o } + \*/ + Snap.path.getPointAtLength = getPointAtLength; + /*\ + * Snap.path.getSubpath + [ method ] + ** + * Returns the subpath of a given path between given start and end lengths + ** + - path (string) SVG path string + - from (number) length, in pixels, from the start of the path to the start of the segment + - to (number) length, in pixels, from the start of the path to the end of the segment + ** + = (string) path string definition for the segment + \*/ + Snap.path.getSubpath = function (path, from, to) { + if (this.getTotalLength(path) - to < 1e-6) { + return getSubpathsAtLength(path, from).end; + } + var a = getSubpathsAtLength(path, to, 1); + return from ? getSubpathsAtLength(a, from).end : a; + }; + /*\ + * Element.getTotalLength + [ method ] + ** + * Returns the length of the path in pixels (only works for `path` elements) + = (number) length + \*/ + elproto.getTotalLength = function () { + if (this.node.getTotalLength) { + return this.node.getTotalLength(); + } + }; + // SIERRA Element.getPointAtLength()/Element.getTotalLength(): If a is broken into different segments, is the jump distance to the new coordinates set by the _M_ or _m_ commands calculated as part of the path's total length? + /*\ + * Element.getPointAtLength + [ method ] + ** + * Returns coordinates of the point located at the given length on the given path (only works for `path` elements) + ** + - length (number) length, in pixels, from the start of the path, excluding non-rendering jumps + ** + = (object) representation of the point: + o { + o x: (number) x coordinate, + o y: (number) y coordinate, + o alpha: (number) angle of derivative + o } + \*/ + elproto.getPointAtLength = function (length) { + return getPointAtLength(this.attr("d"), length); + }; + // SIERRA Element.getSubpath(): Similar to the problem for Element.getPointAtLength(). Unclear how this would work for a segmented path. Overall, the concept of _subpath_ and what I'm calling a _segment_ (series of non-_M_ or _Z_ commands) is unclear. + /*\ + * Element.getSubpath + [ method ] + ** + * Returns subpath of a given element from given start and end lengths (only works for `path` elements) + ** + - from (number) length, in pixels, from the start of the path to the start of the segment + - to (number) length, in pixels, from the start of the path to the end of the segment + ** + = (string) path string definition for the segment + \*/ + elproto.getSubpath = function (from, to) { + return Snap.path.getSubpath(this.attr("d"), from, to); + }; + Snap._.box = box; + /*\ + * Snap.path.findDotsAtSegment + [ method ] + ** + * Utility method + ** + * Finds dot coordinates on the given cubic beziér curve at the given t + - p1x (number) x of the first point of the curve + - p1y (number) y of the first point of the curve + - c1x (number) x of the first anchor of the curve + - c1y (number) y of the first anchor of the curve + - c2x (number) x of the second anchor of the curve + - c2y (number) y of the second anchor of the curve + - p2x (number) x of the second point of the curve + - p2y (number) y of the second point of the curve + - t (number) position on the curve (0..1) + = (object) point information in format: + o { + o x: (number) x coordinate of the point, + o y: (number) y coordinate of the point, + o m: { + o x: (number) x coordinate of the left anchor, + o y: (number) y coordinate of the left anchor + o }, + o n: { + o x: (number) x coordinate of the right anchor, + o y: (number) y coordinate of the right anchor + o }, + o start: { + o x: (number) x coordinate of the start of the curve, + o y: (number) y coordinate of the start of the curve + o }, + o end: { + o x: (number) x coordinate of the end of the curve, + o y: (number) y coordinate of the end of the curve + o }, + o alpha: (number) angle of the curve derivative at the point + o } + \*/ + Snap.path.findDotsAtSegment = findDotsAtSegment; + /*\ + * Snap.path.bezierBBox + [ method ] + ** + * Utility method + ** + * Returns the bounding box of a given cubic beziér curve + - p1x (number) x of the first point of the curve + - p1y (number) y of the first point of the curve + - c1x (number) x of the first anchor of the curve + - c1y (number) y of the first anchor of the curve + - c2x (number) x of the second anchor of the curve + - c2y (number) y of the second anchor of the curve + - p2x (number) x of the second point of the curve + - p2y (number) y of the second point of the curve + * or + - bez (array) array of six points for beziér curve + = (object) bounding box + o { + o x: (number) x coordinate of the left top point of the box, + o y: (number) y coordinate of the left top point of the box, + o x2: (number) x coordinate of the right bottom point of the box, + o y2: (number) y coordinate of the right bottom point of the box, + o width: (number) width of the box, + o height: (number) height of the box + o } + \*/ + Snap.path.bezierBBox = bezierBBox; + /*\ + * Snap.path.isPointInsideBBox + [ method ] + ** + * Utility method + ** + * Returns `true` if given point is inside bounding box + - bbox (string) bounding box + - x (string) x coordinate of the point + - y (string) y coordinate of the point + = (boolean) `true` if point is inside + \*/ + Snap.path.isPointInsideBBox = isPointInsideBBox; + /*\ + * Snap.path.isBBoxIntersect + [ method ] + ** + * Utility method + ** + * Returns `true` if two bounding boxes intersect + - bbox1 (string) first bounding box + - bbox2 (string) second bounding box + = (boolean) `true` if bounding boxes intersect + \*/ + Snap.path.isBBoxIntersect = isBBoxIntersect; + /*\ + * Snap.path.intersection + [ method ] + ** + * Utility method + ** + * Finds intersections of two paths + - path1 (string) path string + - path2 (string) path string + = (array) dots of intersection + o [ + o { + o x: (number) x coordinate of the point, + o y: (number) y coordinate of the point, + o t1: (number) t value for segment of path1, + o t2: (number) t value for segment of path2, + o segment1: (number) order number for segment of path1, + o segment2: (number) order number for segment of path2, + o bez1: (array) eight coordinates representing beziér curve for the segment of path1, + o bez2: (array) eight coordinates representing beziér curve for the segment of path2 + o } + o ] + \*/ + Snap.path.intersection = pathIntersection; + Snap.path.intersectionNumber = pathIntersectionNumber; + /*\ + * Snap.path.isPointInside + [ method ] + ** + * Utility method + ** + * Returns `true` if given point is inside a given closed path. + * + * Note: fill mode doesn’t affect the result of this method. + - path (string) path string + - x (number) x of the point + - y (number) y of the point + = (boolean) `true` if point is inside the path + \*/ + Snap.path.isPointInside = isPointInsidePath; + /*\ + * Snap.path.getBBox + [ method ] + ** + * Utility method + ** + * Returns the bounding box of a given path + - path (string) path string + = (object) bounding box + o { + o x: (number) x coordinate of the left top point of the box, + o y: (number) y coordinate of the left top point of the box, + o x2: (number) x coordinate of the right bottom point of the box, + o y2: (number) y coordinate of the right bottom point of the box, + o width: (number) width of the box, + o height: (number) height of the box + o } + \*/ + Snap.path.getBBox = pathBBox; + Snap.path.get = getPath; + /*\ + * Snap.path.toRelative + [ method ] + ** + * Utility method + ** + * Converts path coordinates into relative values + - path (string) path string + = (array) path string + \*/ + Snap.path.toRelative = pathToRelative; + /*\ + * Snap.path.toAbsolute + [ method ] + ** + * Utility method + ** + * Converts path coordinates into absolute values + - path (string) path string + = (array) path string + \*/ + Snap.path.toAbsolute = pathToAbsolute; + /*\ + * Snap.path.toCubic + [ method ] + ** + * Utility method + ** + * Converts path to a new path where all segments are cubic beziér curves + - pathString (string|array) path string or array of segments + = (array) array of segments + \*/ + Snap.path.toCubic = path2curve; + /*\ + * Snap.path.map + [ method ] + ** + * Transform the path string with the given matrix + - path (string) path string + - matrix (object) see @Matrix + = (string) transformed path string + \*/ + Snap.path.map = mapPath; + Snap.path.toString = toString; + Snap.path.clone = pathClone; +}); +// 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) { + var mmax = Math.max, + mmin = Math.min; + + // Set + var Set = function (items) { + this.items = []; + this.length = 0; + this.type = "set"; + if (items) { + for (var i = 0, ii = items.length; i < ii; i++) { + if (items[i]) { + this[this.items.length] = this.items[this.items.length] = items[i]; + this.length++; + } + } + } + }, + setproto = Set.prototype; + /*\ + * Set.push + [ method ] + ** + * Adds each argument to the current set + = (object) original element + \*/ + setproto.push = function () { + var item, + len; + for (var i = 0, ii = arguments.length; i < ii; i++) { + item = arguments[i]; + if (item) { + len = this.items.length; + this[len] = this.items[len] = item; + this.length++; + } + } + return this; + }; + /*\ + * Set.pop + [ method ] + ** + * Removes last element and returns it + = (object) element + \*/ + setproto.pop = function () { + this.length && delete this[this.length--]; + return this.items.pop(); + }; + /*\ + * Set.forEach + [ method ] + ** + * Executes given function for each element in the set + * + * If the function returns `false`, the loop stops running. + ** + - callback (function) function to run + - thisArg (object) context object for the callback + = (object) Set object + \*/ + setproto.forEach = function (callback, thisArg) { + for (var i = 0, ii = this.items.length; i < ii; i++) { + if (callback.call(thisArg, this.items[i], i) === false) { + return this; + } + } + return this; + }; + setproto.remove = function () { + while (this.length) { + this.pop().remove(); + } + return this; + }; + setproto.attr = function (value) { + for (var i = 0, ii = this.items.length; i < ii; i++) { + this.items[i].attr(value); + } + return this; + }; + /*\ + * Set.clear + [ method ] + ** + * Removes all elements from the set + \*/ + setproto.clear = function () { + while (this.length) { + this.pop(); + } + }; + /*\ + * Set.splice + [ method ] + ** + * Removes range of elements from the set + ** + - index (number) position of the deletion + - count (number) number of element to remove + - insertion… (object) #optional elements to insert + = (object) set elements that were deleted + \*/ + setproto.splice = function (index, count, insertion) { + index = index < 0 ? mmax(this.length + index, 0) : index; + count = mmax(0, mmin(this.length - index, count)); + var tail = [], + todel = [], + args = [], + i; + for (i = 2; i < arguments.length; i++) { + args.push(arguments[i]); + } + for (i = 0; i < count; i++) { + todel.push(this[index + i]); + } + for (; i < this.length - index; i++) { + tail.push(this[index + i]); + } + var arglen = args.length; + for (i = 0; i < arglen + tail.length; i++) { + this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen]; + } + i = this.items.length = this.length -= count - arglen; + while (this[i]) { + delete this[i++]; + } + return new Set(todel); + }; + /*\ + * Set.exclude + [ method ] + ** + * Removes given element from the set + ** + - element (object) element to remove + = (boolean) `true` if object was found and removed from the set + \*/ + setproto.exclude = function (el) { + for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) { + this.splice(i, 1); + return true; + } + return false; + }; + setproto.insertAfter = function (el) { + var i = this.items.length; + while (i--) { + this.items[i].insertAfter(el); + } + return this; + }; + setproto.getBBox = function () { + var x = [], + y = [], + x2 = [], + y2 = []; + for (var i = this.items.length; i--;) if (!this.items[i].removed) { + var box = this.items[i].getBBox(); + x.push(box.x); + y.push(box.y); + x2.push(box.x + box.width); + y2.push(box.y + box.height); + } + x = mmin.apply(0, x); + y = mmin.apply(0, y); + x2 = mmax.apply(0, x2); + y2 = mmax.apply(0, y2); + return { + x: x, + y: y, + x2: x2, + y2: y2, + width: x2 - x, + height: y2 - y, + cx: x + (x2 - x) / 2, + cy: y + (y2 - y) / 2 + }; + }; + setproto.clone = function (s) { + s = new Set; + for (var i = 0, ii = this.items.length; i < ii; i++) { + s.push(this.items[i].clone()); + } + return s; + }; + setproto.toString = function () { + return "Snap\u2018s set"; + }; + setproto.type = "set"; + // export + Snap.set = function () { + var set = new Set; + if (arguments.length) { + set.push.apply(set, Array.prototype.slice.call(arguments, 0)); + } + return set; + }; +}); +// 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) { + var names = {}, + reUnit = /[a-z]+$/i, + Str = String; + names.stroke = names.fill = "colour"; + function getEmpty(item) { + var l = item[0]; + switch (l.toLowerCase()) { + case "t": return [l, 0, 0]; + case "m": return [l, 1, 0, 0, 1, 0, 0]; + case "r": if (item.length == 4) { + return [l, 0, item[2], item[3]]; + } else { + return [l, 0]; + } + case "s": if (item.length == 5) { + return [l, 1, 1, item[3], item[4]]; + } else if (item.length == 3) { + return [l, 1, 1]; + } else { + return [l, 1]; + } + } + } + function equaliseTransform(t1, t2, getBBox) { + t2 = Str(t2).replace(/\.{3}|\u2026/g, t1); + t1 = Snap.parseTransformString(t1) || []; + t2 = Snap.parseTransformString(t2) || []; + var maxlength = Math.max(t1.length, t2.length), + from = [], + to = [], + i = 0, j, jj, + tt1, tt2; + for (; i < maxlength; i++) { + tt1 = t1[i] || getEmpty(t2[i]); + tt2 = t2[i] || getEmpty(tt1); + if ((tt1[0] != tt2[0]) || + (tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) || + (tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4])) + ) { + t1 = Snap._.transform2matrix(t1, getBBox()); + t2 = Snap._.transform2matrix(t2, getBBox()); + from = [["m", t1.a, t1.b, t1.c, t1.d, t1.e, t1.f]]; + to = [["m", t2.a, t2.b, t2.c, t2.d, t2.e, t2.f]]; + break; + } + from[i] = []; + to[i] = []; + for (j = 0, jj = Math.max(tt1.length, tt2.length); j < jj; j++) { + j in tt1 && (from[i][j] = tt1[j]); + j in tt2 && (to[i][j] = tt2[j]); + } + } + return { + from: path2array(from), + to: path2array(to), + f: getPath(from) + }; + } + function getNumber(val) { + return val; + } + function getUnit(unit) { + return function (val) { + return +val.toFixed(3) + unit; + }; + } + function getColour(clr) { + return Snap.rgb(clr[0], clr[1], clr[2]); + } + function getPath(path) { + var k = 0, i, ii, j, jj, out, a, b = []; + for (i = 0, ii = path.length; i < ii; i++) { + out = "["; + a = ['"' + path[i][0] + '"']; + for (j = 1, jj = path[i].length; j < jj; j++) { + a[j] = "val[" + (k++) + "]"; + } + out += a + "]"; + b[i] = out; + } + return Function("val", "return Snap.path.toString.call([" + b + "])"); + } + function path2array(path) { + var out = []; + for (var i = 0, ii = path.length; i < ii; i++) { + for (var j = 1, jj = path[i].length; j < jj; j++) { + out.push(path[i][j]); + } + } + return out; + } + Element.prototype.equal = function (name, b) { + var A, B, a = Str(this.attr(name) || ""), + el = this; + if (a == +a && b == +b) { + return { + from: +a, + to: +b, + f: getNumber + }; + } + if (names[name] == "colour") { + A = Snap.color(a); + B = Snap.color(b); + return { + from: [A.r, A.g, A.b, A.opacity], + to: [B.r, B.g, B.b, B.opacity], + f: getColour + }; + } + if (name == "transform" || name == "gradientTransform" || name == "patternTransform") { + if (b instanceof Snap.Matrix) { + b = b.toTransformString(); + } + if (!Snap._.rgTransform.test(b)) { + b = Snap._.svgTransform2string(b); + } + return equaliseTransform(a, b, function () { + return el.getBBox(1); + }); + } + if (name == "d" || name == "path") { + A = Snap.path.toCubic(a, b); + return { + from: path2array(A[0]), + to: path2array(A[1]), + f: getPath(A[0]) + }; + } + if (name == "points") { + A = Str(a).split(","); + B = Str(b).split(","); + return { + from: A, + to: B, + f: function (val) { return val; } + }; + } + var aUnit = a.match(reUnit), + bUnit = Str(b).match(reUnit); + if (aUnit && aUnit == bUnit) { + return { + from: parseFloat(a), + to: parseFloat(b), + f: getUnit(aUnit) + }; + } else { + return { + from: this.asPX(name), + to: this.asPX(name, b), + f: getNumber + }; + } + }; +}); +// 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) { + var elproto = Element.prototype, + has = "hasOwnProperty", + supportsTouch = "createTouch" in glob.doc, + events = [ + "click", "dblclick", "mousedown", "mousemove", "mouseout", + "mouseover", "mouseup", "touchstart", "touchmove", "touchend", + "touchcancel" + ], + touchMap = { + mousedown: "touchstart", + mousemove: "touchmove", + mouseup: "touchend" + }, + getScroll = function (xy) { + var name = xy == "y" ? "scrollTop" : "scrollLeft"; + return glob.doc.documentElement[name] || glob.doc.body[name]; + }, + preventDefault = function () { + this.returnValue = false; + }, + preventTouch = function () { + return this.originalEvent.preventDefault(); + }, + stopPropagation = function () { + this.cancelBubble = true; + }, + stopTouch = function () { + return this.originalEvent.stopPropagation(); + }, + addEvent = (function () { + if (glob.doc.addEventListener) { + return function (obj, type, fn, element) { + var realName = supportsTouch && touchMap[type] ? touchMap[type] : type, + f = function (e) { + var scrollY = getScroll("y"), + scrollX = getScroll("x"); + if (supportsTouch && touchMap[has](type)) { + for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) { + if (e.targetTouches[i].target == obj || obj.contains(e.targetTouches[i].target)) { + var olde = e; + e = e.targetTouches[i]; + e.originalEvent = olde; + e.preventDefault = preventTouch; + e.stopPropagation = stopTouch; + break; + } + } + } + var x = e.clientX + scrollX, + y = e.clientY + scrollY; + return fn.call(element, e, x, y); + }; + + if (type !== realName) { + obj.addEventListener(type, f, false); + } + + obj.addEventListener(realName, f, false); + + return function () { + if (type !== realName) { + obj.removeEventListener(type, f, false); + } + + obj.removeEventListener(realName, f, false); + return true; + }; + }; + } else if (glob.doc.attachEvent) { + return function (obj, type, fn, element) { + var f = function (e) { + e = e || glob.win.event; + var scrollY = getScroll("y"), + scrollX = getScroll("x"), + x = e.clientX + scrollX, + y = e.clientY + scrollY; + e.preventDefault = e.preventDefault || preventDefault; + e.stopPropagation = e.stopPropagation || stopPropagation; + return fn.call(element, e, x, y); + }; + obj.attachEvent("on" + type, f); + var detacher = function () { + obj.detachEvent("on" + type, f); + return true; + }; + return detacher; + }; + } + })(), + drag = [], + dragMove = function (e) { + var x = e.clientX, + y = e.clientY, + scrollY = getScroll("y"), + scrollX = getScroll("x"), + dragi, + j = drag.length; + while (j--) { + dragi = drag[j]; + if (supportsTouch) { + var i = e.touches && e.touches.length, + touch; + while (i--) { + touch = e.touches[i]; + if (touch.identifier == dragi.el._drag.id || dragi.el.node.contains(touch.target)) { + x = touch.clientX; + y = touch.clientY; + (e.originalEvent ? e.originalEvent : e).preventDefault(); + break; + } + } + } else { + e.preventDefault(); + } + var node = dragi.el.node, + o, + glob = Snap._.glob, + next = node.nextSibling, + parent = node.parentNode, + display = node.style.display; + // glob.win.opera && parent.removeChild(node); + // node.style.display = "none"; + // o = dragi.el.paper.getElementByPoint(x, y); + // node.style.display = display; + // glob.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node)); + // o && eve("snap.drag.over." + dragi.el.id, dragi.el, o); + x += scrollX; + y += scrollY; + eve("snap.drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e); + } + }, + dragUp = function (e) { + Snap.unmousemove(dragMove).unmouseup(dragUp); + var i = drag.length, + dragi; + while (i--) { + dragi = drag[i]; + dragi.el._drag = {}; + eve("snap.drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e); + } + drag = []; + }; + /*\ + * Element.click + [ method ] + ** + * Adds a click event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unclick + [ method ] + ** + * Removes a click event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.dblclick + [ method ] + ** + * Adds a double click event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.undblclick + [ method ] + ** + * Removes a double click event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mousedown + [ method ] + ** + * Adds a mousedown event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmousedown + [ method ] + ** + * Removes a mousedown event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mousemove + [ method ] + ** + * Adds a mousemove event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmousemove + [ method ] + ** + * Removes a mousemove event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mouseout + [ method ] + ** + * Adds a mouseout event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmouseout + [ method ] + ** + * Removes a mouseout event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mouseover + [ method ] + ** + * Adds a mouseover event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmouseover + [ method ] + ** + * Removes a mouseover event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mouseup + [ method ] + ** + * Adds a mouseup event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmouseup + [ method ] + ** + * Removes a mouseup event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.touchstart + [ method ] + ** + * Adds a touchstart event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.untouchstart + [ method ] + ** + * Removes a touchstart event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.touchmove + [ method ] + ** + * Adds a touchmove event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.untouchmove + [ method ] + ** + * Removes a touchmove event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.touchend + [ method ] + ** + * Adds a touchend event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.untouchend + [ method ] + ** + * Removes a touchend event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.touchcancel + [ method ] + ** + * Adds a touchcancel event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.untouchcancel + [ method ] + ** + * Removes a touchcancel event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + for (var i = events.length; i--;) { + (function (eventName) { + Snap[eventName] = elproto[eventName] = function (fn, scope) { + if (Snap.is(fn, "function")) { + this.events = this.events || []; + this.events.push({ + name: eventName, + f: fn, + unbind: addEvent(this.shape || this.node || glob.doc, eventName, fn, scope || this) + }); + } + return this; + }; + Snap["un" + eventName] = + elproto["un" + eventName] = function (fn) { + var events = this.events || [], + l = events.length; + while (l--) if (events[l].name == eventName && + (events[l].f == fn || !fn)) { + events[l].unbind(); + events.splice(l, 1); + !events.length && delete this.events; + return this; + } + return this; + }; + })(events[i]); + } + /*\ + * Element.hover + [ method ] + ** + * Adds hover event handlers to the element + - f_in (function) handler for hover in + - f_out (function) handler for hover out + - icontext (object) #optional context for hover in handler + - ocontext (object) #optional context for hover out handler + = (object) @Element + \*/ + elproto.hover = function (f_in, f_out, scope_in, scope_out) { + return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in); + }; + /*\ + * Element.unhover + [ method ] + ** + * Removes hover event handlers from the element + - f_in (function) handler for hover in + - f_out (function) handler for hover out + = (object) @Element + \*/ + elproto.unhover = function (f_in, f_out) { + return this.unmouseover(f_in).unmouseout(f_out); + }; + var draggable = []; + // SIERRA unclear what _context_ refers to for starting, ending, moving the drag gesture. + // SIERRA Element.drag(): _x position of the mouse_: Where are the x/y values offset from? + // SIERRA Element.drag(): much of this member's doc appears to be duplicated for some reason. + // SIERRA Unclear about this sentence: _Additionally following drag events will be triggered: drag.start. on start, drag.end. on end and drag.move. on every move._ Is there a global _drag_ object to which you can assign handlers keyed by an element's ID? + /*\ + * Element.drag + [ method ] + ** + * Adds event handlers for an element's drag gesture + ** + - onmove (function) handler for moving + - onstart (function) handler for drag start + - onend (function) handler for drag end + - mcontext (object) #optional context for moving handler + - scontext (object) #optional context for drag start handler + - econtext (object) #optional context for drag end handler + * Additionaly following `drag` events are triggered: `drag.start.` on start, + * `drag.end.` on end and `drag.move.` on every move. When element is dragged over another element + * `drag.over.` fires as well. + * + * Start event and start handler are called in specified context or in context of the element with following parameters: + o x (number) x position of the mouse + o y (number) y position of the mouse + o event (object) DOM event object + * Move event and move handler are called in specified context or in context of the element with following parameters: + o dx (number) shift by x from the start point + o dy (number) shift by y from the start point + o x (number) x position of the mouse + o y (number) y position of the mouse + o event (object) DOM event object + * End event and end handler are called in specified context or in context of the element with following parameters: + o event (object) DOM event object + = (object) @Element + \*/ + elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) { + if (!arguments.length) { + var origTransform; + return this.drag(function (dx, dy) { + this.attr({ + transform: origTransform + (origTransform ? "T" : "t") + [dx, dy] + }); + }, function () { + origTransform = this.transform().local; + }); + } + function start(e, x, y) { + (e.originalEvent || e).preventDefault(); + this._drag.x = x; + this._drag.y = y; + this._drag.id = e.identifier; + !drag.length && Snap.mousemove(dragMove).mouseup(dragUp); + drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope}); + onstart && eve.on("snap.drag.start." + this.id, onstart); + onmove && eve.on("snap.drag.move." + this.id, onmove); + onend && eve.on("snap.drag.end." + this.id, onend); + eve("snap.drag.start." + this.id, start_scope || move_scope || this, x, y, e); + } + this._drag = {}; + draggable.push({el: this, start: start}); + this.mousedown(start); + return this; + }; + /* + * Element.onDragOver + [ method ] + ** + * Shortcut to assign event handler for `drag.over.` event, where `id` is the element's `id` (see @Element.id) + - f (function) handler for event, first argument would be the element you are dragging over + \*/ + // elproto.onDragOver = function (f) { + // f ? eve.on("snap.drag.over." + this.id, f) : eve.unbind("snap.drag.over." + this.id); + // }; + /*\ + * Element.undrag + [ method ] + ** + * Removes all drag event handlers from the given element + \*/ + elproto.undrag = function () { + var i = draggable.length; + while (i--) if (draggable[i].el == this) { + this.unmousedown(draggable[i].start); + draggable.splice(i, 1); + eve.unbind("snap.drag.*." + this.id); + } + !draggable.length && Snap.unmousemove(dragMove).unmouseup(dragUp); + return this; + }; +}); +// 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) { + var elproto = Element.prototype, + pproto = Paper.prototype, + rgurl = /^\s*url\((.+)\)/, + Str = String, + $ = Snap._.$; + Snap.filter = {}; +// SIERRA Paper.filter(): I don't understand the note. Does that mean an HTML should dedicate a separate SVG region for a filter definition? What's the advantage over a DEFS? + /*\ + * Paper.filter + [ method ] + ** + * Creates a `` element + ** + - filstr (string) SVG fragment of filter provided as a string + = (object) @Element + * Note: It is recommended to use filters embedded into the page inside an empty SVG element. + > Usage + | var f = paper.filter(''), + | c = paper.circle(10, 10, 10).attr({ + | filter: f + | }); + \*/ + pproto.filter = function (filstr) { + var paper = this; + if (paper.type != "svg") { + paper = paper.paper; + } + var f = Snap.parse(Str(filstr)), + id = Snap._.id(), + width = paper.node.offsetWidth, + height = paper.node.offsetHeight, + filter = $("filter"); + $(filter, { + id: id, + filterUnits: "userSpaceOnUse" + }); + filter.appendChild(f.node); + paper.defs.appendChild(filter); + return new Element(filter); + }; + + eve.on("snap.util.getattr.filter", function () { + eve.stop(); + var p = $(this.node, "filter"); + if (p) { + var match = Str(p).match(rgurl); + return match && Snap.select(match[1]); + } + }); + eve.on("snap.util.attr.filter", function (value) { + if (value instanceof Element && value.type == "filter") { + eve.stop(); + var id = value.node.id; + if (!id) { + $(value.node, {id: value.id}); + id = value.id; + } + $(this.node, { + filter: Snap.url(id) + }); + } + if (!value || value == "none") { + eve.stop(); + this.node.removeAttribute("filter"); + } + }); + /*\ + * Snap.filter.blur + [ method ] + ** + * Returns an SVG markup string for the blur filter + ** + - x (number) amount of horizontal blur, in pixels + - y (number) #optional amount of vertical blur, in pixels + = (string) filter representation + > Usage + | var f = paper.filter(Snap.filter.blur(5, 10)), + | c = paper.circle(10, 10, 10).attr({ + | filter: f + | }); + \*/ + Snap.filter.blur = function (x, y) { + if (x == null) { + x = 2; + } + var def = y == null ? x : [x, y]; + return Snap.format('\', { + def: def + }); + }; + Snap.filter.blur.toString = function () { + return this(); + }; + /*\ + * Snap.filter.shadow + [ method ] + ** + * Returns an SVG markup string for the shadow filter + ** + - dx (number) horizontal shift of the shadow, in pixels + - dy (number) vertical shift of the shadow, in pixels + - blur (number) #optional amount of blur + - color (string) #optional color of the shadow + = (string) filter representation + > Usage + | var f = paper.filter(Snap.filter.shadow(0, 2, 3)), + | c = paper.circle(10, 10, 10).attr({ + | filter: f + | }); + \*/ + Snap.filter.shadow = function (dx, dy, blur, color) { + color = color || "#000"; + if (blur == null) { + blur = 4; + } + if (typeof blur == "string") { + color = blur; + blur = 4; + } + if (dx == null) { + dx = 0; + dy = 2; + } + if (dy == null) { + dy = dx; + } + color = Snap.color(color); + return Snap.format('', { + color: color, + dx: dx, + dy: dy, + blur: blur + }); + }; + Snap.filter.shadow.toString = function () { + return this(); + }; + /*\ + * Snap.filter.grayscale + [ method ] + ** + * Returns an SVG markup string for the grayscale filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.grayscale = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + a: 0.2126 + 0.7874 * (1 - amount), + b: 0.7152 - 0.7152 * (1 - amount), + c: 0.0722 - 0.0722 * (1 - amount), + d: 0.2126 - 0.2126 * (1 - amount), + e: 0.7152 + 0.2848 * (1 - amount), + f: 0.0722 - 0.0722 * (1 - amount), + g: 0.2126 - 0.2126 * (1 - amount), + h: 0.0722 + 0.9278 * (1 - amount) + }); + }; + Snap.filter.grayscale.toString = function () { + return this(); + }; + /*\ + * Snap.filter.sepia + [ method ] + ** + * Returns an SVG markup string for the sepia filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.sepia = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + a: 0.393 + 0.607 * (1 - amount), + b: 0.769 - 0.769 * (1 - amount), + c: 0.189 - 0.189 * (1 - amount), + d: 0.349 - 0.349 * (1 - amount), + e: 0.686 + 0.314 * (1 - amount), + f: 0.168 - 0.168 * (1 - amount), + g: 0.272 - 0.272 * (1 - amount), + h: 0.534 - 0.534 * (1 - amount), + i: 0.131 + 0.869 * (1 - amount) + }); + }; + Snap.filter.sepia.toString = function () { + return this(); + }; + /*\ + * Snap.filter.saturate + [ method ] + ** + * Returns an SVG markup string for the saturate filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.saturate = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + amount: 1 - amount + }); + }; + Snap.filter.saturate.toString = function () { + return this(); + }; + /*\ + * Snap.filter.hueRotate + [ method ] + ** + * Returns an SVG markup string for the hue-rotate filter + ** + - angle (number) angle of rotation + = (string) filter representation + \*/ + Snap.filter.hueRotate = function (angle) { + angle = angle || 0; + return Snap.format('', { + angle: angle + }); + }; + Snap.filter.hueRotate.toString = function () { + return this(); + }; + /*\ + * Snap.filter.invert + [ method ] + ** + * Returns an SVG markup string for the invert filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.invert = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + amount: amount, + amount2: 1 - amount + }); + }; + Snap.filter.invert.toString = function () { + return this(); + }; + /*\ + * Snap.filter.brightness + [ method ] + ** + * Returns an SVG markup string for the brightness filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.brightness = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + amount: amount + }); + }; + Snap.filter.brightness.toString = function () { + return this(); + }; + /*\ + * Snap.filter.contrast + [ method ] + ** + * Returns an SVG markup string for the contrast filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.contrast = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + amount: amount, + amount2: .5 - amount / 2 + }); + }; + Snap.filter.contrast.toString = function () { + return this(); + }; +}); +return Snap; +})); +define('app/heart',['require'],function (require) { + + var Heart = function (s, x, y) { + var instance = this, + heart, + heartMatrix, + totalMaskVertices = 50; + + this.el = s.select("#heart"); + heart = this.el.select('#heart-shape'); + + instance.maskElement = s.path(getPath(totalMaskVertices)); + instance.el.attr({ + clipPath: instance.maskElement + }); + + this.animFill = function (f, dur) { + heart.animate({ + fill: f + }, 200); + } + + this.setFill = function (f, dur) { + heart.attr({ + fill: f + }, 200); + } + + this.animScale = function (scale, dur) { + dur = dur ? dur : 300; + + this.matrix = new Snap.Matrix(); + this.matrix.translate(x, y); + this.matrix.scale(scale); + this.el.animate({ + transform: this.matrix.toTransformString() + }, dur, mina.bounce); + } + + this.setScale = function (scale, dur) { + dur = dur ? dur : 300; + + this.matrix = new Snap.Matrix(); + this.matrix.translate(x, y); + this.matrix.scale(scale, scale, 0, 0); + this.el.attr({ + transform: this.matrix.toTransformString() + }); + + } + + this.mask = function () { + var n = totalMaskVertices; + + instance.maskElement.attr({ + d: getPath(n) + }); + + function updatePath() { + n -= 1; + instance.maskElement.attr({ + d: getPath(n) + }); + + if (n > 0) { + setTimeout(updatePath, 10); + } + } + + setTimeout(updatePath, 10); + } + + this.unmask = function () { + instance.maskElement.attr({ + d: getPath(totalMaskVertices) + }); + } + + function getPath(n) { + var pathString, + i, + _x, + _y; + + pathString = "M0 0"; + + for (i = 0; i < n + 1; i += 1) { + a = 2 * Math.PI * i / totalMaskVertices; + a += Math.PI; + + _x = Math.sin(a) * 50; + _y = Math.cos(a) * 50; + + pathString += "L" + _x + " " + _y; + } + + pathString += "Z"; + return pathString; + } + } + + return Heart; +}); +define('app/device',['require'],function (require) { + + var Device = function (s, x, y) { + var instance = this; + + this.el = s.g(); + this.matrix = new Snap.Matrix(); + this.matrix.translate(x, y); + this.el.transform(this.matrix.toTransformString()); + + this.keyboardMatrix = new Snap.Matrix(); + this.keyboardMatrix.translate(0, 70); + + instance.maskElement = s.polygon(); + instance.maskElement.toDefs(); + + addBack(); + addScreen(); + //addGloss(); + addKeyboard(); + + function addBack() { + instance.back = s.rect(0, 0, 0, 0); + instance.back.attr({ + fill: '#696969' + }); + + instance.el.append(instance.back); + } + + function addScreen() { + instance.scr = s.rect(0, 0, 0, 0); + instance.scr.attr({ + fill: "#09ae8a" + }); + + instance.el.append(instance.scr); + } + + function addKeyboard() { + var p1, + p2; + + instance.keyboard = s.g(); + instance.keyboard.transform(instance.keyboardMatrix.toTransformString()); + + p1 = s.polygon('-103.324,0 -135.324,32 136.676,32 104.676,0 '); + p1.attr({ + fill: '#818181' + }); + + p2 = s.polygon('127.774,40 -128.226,40 -136.226,32 135.774,32 '); + p2.attr({ + fill: '#676767' + }); + + instance.keyboard.append(p1); + instance.keyboard.append(p2); + instance.el.append(instance.keyboard); + } + + function addGloss() { + instance.gl = s.rect(0, 0, 0, 0); + instance.gl.attr({ + opacity: 0.2, + fill: "white", + clipPath: instance.maskElement + }); + + instance.el.append(instance.gl); + } + + this.hideKeyboard = function () { + this.keyboardMatrix = new Snap.Matrix(); + instance.keyboardMatrix.translate(0, 50); + instance.keyboardMatrix.scale(0.01, 0.01, 0, 0); + instance.keyboard.animate({ + opacity: 0, + transform: instance.keyboardMatrix.toTransformString() + }, 100); + } + + this.showKeyboard = function () { + this.keyboardMatrix = new Snap.Matrix(); + instance.keyboardMatrix.translate(0, 70); + instance.keyboardMatrix.scale(1, 1, 0, 0); + instance.keyboard.attr({ + opacity: 1, + transform: instance.keyboardMatrix.toTransformString() + }); + } + + this.setScreen = function(w, h) { + this.scr.attr({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }); + } + + this.setBack = function (w, h) { + this.back.attr({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }); + + /* + this.gl.attr({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }); + + var pointString = -w / 2 + ' ' + -h / 2 + ',' + w / 2 + ' ' + -h / 2 + ',' + -w / 2 + ' ' + h / 2; + + instance.maskElement.attr({ + points: pointString + }); + */ + } + + this.setScale = function (scale) { + this.matrix.scale(scale, scale, 0, 0); + this.el.transform(this.matrix.toTransformString()); + } + + this.animScreen = function(w, h) { + this.scr.animate({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }, 100); + } + + this.animBack = function (w, h) { + this.back.animate({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }, 100); + + /* + this.gl.animate({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }, 100); + + var pointString = -w / 2 + ' ' + -h / 2 + ',' + w / 2 + ' ' + -h / 2 + ',' + -w / 2 + ' ' + h / 2; + + instance.maskElement.attr({ + points: pointString + }); + */ + } + + this.animRotation = function (r) { + instance.matrix.rotate(r, 0, 0); + + instance.el.animate({ + transform: instance.matrix.toTransformString() + }, 100, mina.easeIn); + + /* + if (r == 90) { + var w = 100, + h = 56, + pointString = -w / 2 + ' ' + -h / 2 + ',' + w / 2 + ' ' + -h / 2 + ',' + -w / 2 + ' ' + h / 2; + + instance.maskElement.attr({ + points: pointString + }); + + instance.maskElement.animate({ + transform: 'rotate(-90)' + }, 100, mina.easeIn); + } else { + instance.maskElement.animate({ + transform: 'rotate(0)' + }, 100, mina.easeIn); + } + */ + } + + this.animScale = function (scale, dur, ease) { + dur = dur ? dur : 100; + ease = ease ? ease : mina.easeout; + + this.matrix.scale(scale, scale, 0, 0); + this.el.animate({ + transform: this.matrix.toTransformString() + }, dur, ease); + } + + this.animOpacity = function (opacity, dur) { + dur = dur ? dur : 200; + + this.el.animate({ + opacity: opacity + }, dur); + } + + this.setOpacity = function (opacity) { + this.el.attr({ + opacity: opacity + }); + } + } + + return Device; +}); +define('app/burst',['require'],function (require) { + + var Burst = function (s, x, y) { + var instance = this, + polygons, + mask, + maskCircle, + maskBg; + + this.el = s.select("#burst"); + + mask = s.g(); + mask.toDefs(); + + maskBg = s.rect(-200, -200, 400, 400); + maskBg.attr({ + fill: 'white' + }); + mask.append(maskBg); + + maskCircle = s.circle(0, 0, 30); + mask.append(maskCircle); + + this.el.attr({ + mask: mask + }); + + this.anim = function () { + this.el.animate({ + opacity: 1 + }, 100); + + maskCircle.animate({ + transform: 'scale(6)' + }, 300); + + setTimeout(function () { + instance.el.animate({ + opacity: 0 + }, 100); + }, 300) + } + + this.reset = function () { + maskCircle.attr({ + transform: 'scale(1)' + }); + } + } + + return Burst; +}); +//============================================================ +// +// Copyright (C) 2013 Matthew Wagerfield +// +// Twitter: https://twitter.com/mwagerfield +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, +// sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY +// OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +// +//============================================================ + +/** + * Defines the Flat Surface Shader namespace for all the awesomeness to exist upon. + * @author Matthew Wagerfield + */ +FSS = { + FRONT : 0, + BACK : 1, + DOUBLE : 2, + SVGNS : 'http://www.w3.org/2000/svg' +}; + +/** + * @class Array + * @author Matthew Wagerfield + */ +FSS.Array = typeof Float32Array === 'function' ? Float32Array : Array; + +/** + * @class Utils + * @author Matthew Wagerfield + */ +FSS.Utils = { + isNumber: function(value) { + return !isNaN(parseFloat(value)) && isFinite(value); + } +}; + +/** + * Request Animation Frame Polyfill. + * @author Paul Irish + * @see https://gist.github.com/paulirish/1579671 + */ +(function() { + + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function(callback, element) { + var currentTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currentTime - lastTime)); + var id = window.setTimeout(function() { + callback(currentTime + timeToCall); + }, timeToCall); + lastTime = currentTime + timeToCall; + return id; + }; + } + + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; + } + +}()); + +/** + * @object Math Augmentation + * @author Matthew Wagerfield + */ +Math.PIM2 = Math.PI*2; +Math.PID2 = Math.PI/2; +Math.randomInRange = function(min, max) { + return min + (max - min) * Math.random(); +}; +Math.clamp = function(value, min, max) { + value = Math.max(value, min); + value = Math.min(value, max); + return value; +}; + +/** + * @object Vector3 + * @author Matthew Wagerfield + */ +FSS.Vector3 = { + create: function(x, y, z) { + var vector = new FSS.Array(3); + this.set(vector, x, y, z); + return vector; + }, + clone: function(a) { + var vector = this.create(); + this.copy(vector, a); + return vector; + }, + set: function(target, x, y, z) { + target[0] = x || 0; + target[1] = y || 0; + target[2] = z || 0; + return this; + }, + setX: function(target, x) { + target[0] = x || 0; + return this; + }, + setY: function(target, y) { + target[1] = y || 0; + return this; + }, + setZ: function(target, z) { + target[2] = z || 0; + return this; + }, + copy: function(target, a) { + target[0] = a[0]; + target[1] = a[1]; + target[2] = a[2]; + return this; + }, + add: function(target, a) { + target[0] += a[0]; + target[1] += a[1]; + target[2] += a[2]; + return this; + }, + addVectors: function(target, a, b) { + target[0] = a[0] + b[0]; + target[1] = a[1] + b[1]; + target[2] = a[2] + b[2]; + return this; + }, + addScalar: function(target, s) { + target[0] += s; + target[1] += s; + target[2] += s; + return this; + }, + subtract: function(target, a) { + target[0] -= a[0]; + target[1] -= a[1]; + target[2] -= a[2]; + return this; + }, + subtractVectors: function(target, a, b) { + target[0] = a[0] - b[0]; + target[1] = a[1] - b[1]; + target[2] = a[2] - b[2]; + return this; + }, + subtractScalar: function(target, s) { + target[0] -= s; + target[1] -= s; + target[2] -= s; + return this; + }, + multiply: function(target, a) { + target[0] *= a[0]; + target[1] *= a[1]; + target[2] *= a[2]; + return this; + }, + multiplyVectors: function(target, a, b) { + target[0] = a[0] * b[0]; + target[1] = a[1] * b[1]; + target[2] = a[2] * b[2]; + return this; + }, + multiplyScalar: function(target, s) { + target[0] *= s; + target[1] *= s; + target[2] *= s; + return this; + }, + divide: function(target, a) { + target[0] /= a[0]; + target[1] /= a[1]; + target[2] /= a[2]; + return this; + }, + divideVectors: function(target, a, b) { + target[0] = a[0] / b[0]; + target[1] = a[1] / b[1]; + target[2] = a[2] / b[2]; + return this; + }, + divideScalar: function(target, s) { + if (s !== 0) { + target[0] /= s; + target[1] /= s; + target[2] /= s; + } else { + target[0] = 0; + target[1] = 0; + target[2] = 0; + } + return this; + }, + cross: function(target, a) { + var x = target[0]; + var y = target[1]; + var z = target[2]; + target[0] = y*a[2] - z*a[1]; + target[1] = z*a[0] - x*a[2]; + target[2] = x*a[1] - y*a[0]; + return this; + }, + crossVectors: function(target, a, b) { + target[0] = a[1]*b[2] - a[2]*b[1]; + target[1] = a[2]*b[0] - a[0]*b[2]; + target[2] = a[0]*b[1] - a[1]*b[0]; + return this; + }, + min: function(target, value) { + if (target[0] < value) { target[0] = value; } + if (target[1] < value) { target[1] = value; } + if (target[2] < value) { target[2] = value; } + return this; + }, + max: function(target, value) { + if (target[0] > value) { target[0] = value; } + if (target[1] > value) { target[1] = value; } + if (target[2] > value) { target[2] = value; } + return this; + }, + clamp: function(target, min, max) { + this.min(target, min); + this.max(target, max); + return this; + }, + limit: function(target, min, max) { + var length = this.length(target); + if (min !== null && length < min) { + this.setLength(target, min); + } else if (max !== null && length > max) { + this.setLength(target, max); + } + return this; + }, + dot: function(a, b) { + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; + }, + normalise: function(target) { + return this.divideScalar(target, this.length(target)); + }, + negate: function(target) { + return this.multiplyScalar(target, -1); + }, + distanceSquared: function(a, b) { + var dx = a[0] - b[0]; + var dy = a[1] - b[1]; + var dz = a[2] - b[2]; + return dx*dx + dy*dy + dz*dz; + }, + distance: function(a, b) { + return Math.sqrt(this.distanceSquared(a, b)); + }, + lengthSquared: function(a) { + return a[0]*a[0] + a[1]*a[1] + a[2]*a[2]; + }, + length: function(a) { + return Math.sqrt(this.lengthSquared(a)); + }, + setLength: function(target, l) { + var length = this.length(target); + if (length !== 0 && l !== length) { + this.multiplyScalar(target, l / length); + } + return this; + } +}; + +/** + * @object Vector4 + * @author Matthew Wagerfield + */ +FSS.Vector4 = { + create: function(x, y, z, w) { + var vector = new FSS.Array(4); + this.set(vector, x, y, z); + return vector; + }, + set: function(target, x, y, z, w) { + target[0] = x || 0; + target[1] = y || 0; + target[2] = z || 0; + target[3] = w || 0; + return this; + }, + setX: function(target, x) { + target[0] = x || 0; + return this; + }, + setY: function(target, y) { + target[1] = y || 0; + return this; + }, + setZ: function(target, z) { + target[2] = z || 0; + return this; + }, + setW: function(target, w) { + target[3] = w || 0; + return this; + }, + add: function(target, a) { + target[0] += a[0]; + target[1] += a[1]; + target[2] += a[2]; + target[3] += a[3]; + return this; + }, + multiplyVectors: function(target, a, b) { + target[0] = a[0] * b[0]; + target[1] = a[1] * b[1]; + target[2] = a[2] * b[2]; + target[3] = a[3] * b[3]; + return this; + }, + multiplyScalar: function(target, s) { + target[0] *= s; + target[1] *= s; + target[2] *= s; + target[3] *= s; + return this; + }, + min: function(target, value) { + if (target[0] < value) { target[0] = value; } + if (target[1] < value) { target[1] = value; } + if (target[2] < value) { target[2] = value; } + if (target[3] < value) { target[3] = value; } + return this; + }, + max: function(target, value) { + if (target[0] > value) { target[0] = value; } + if (target[1] > value) { target[1] = value; } + if (target[2] > value) { target[2] = value; } + if (target[3] > value) { target[3] = value; } + return this; + }, + clamp: function(target, min, max) { + this.min(target, min); + this.max(target, max); + return this; + } +}; + +/** + * @class Color + * @author Matthew Wagerfield + */ +FSS.Color = function(hex, opacity) { + this.rgba = FSS.Vector4.create(); + this.hex = hex || '#000000'; + this.opacity = FSS.Utils.isNumber(opacity) ? opacity : 1; + this.set(this.hex, this.opacity); +}; + +FSS.Color.prototype = { + set: function(hex, opacity) { + hex = hex.replace('#', ''); + var size = hex.length / 3; + this.rgba[0] = parseInt(hex.substring(size*0, size*1), 16) / 255; + this.rgba[1] = parseInt(hex.substring(size*1, size*2), 16) / 255; + this.rgba[2] = parseInt(hex.substring(size*2, size*3), 16) / 255; + this.rgba[3] = FSS.Utils.isNumber(opacity) ? opacity : this.rgba[3]; + return this; + }, + hexify: function(channel) { + var hex = Math.ceil(channel*255).toString(16); + if (hex.length === 1) { hex = '0' + hex; } + return hex; + }, + format: function() { + var r = this.hexify(this.rgba[0]); + var g = this.hexify(this.rgba[1]); + var b = this.hexify(this.rgba[2]); + this.hex = '#' + r + g + b; + return this.hex; + } +}; + +/** + * @class Object + * @author Matthew Wagerfield + */ +FSS.Object = function() { + this.position = FSS.Vector3.create(); +}; + +FSS.Object.prototype = { + setPosition: function(x, y, z) { + FSS.Vector3.set(this.position, x, y, z); + return this; + } +}; + +/** + * @class Light + * @author Matthew Wagerfield + */ +FSS.Light = function(ambient, diffuse) { + FSS.Object.call(this); + this.ambient = new FSS.Color(ambient || '#FFFFFF'); + this.diffuse = new FSS.Color(diffuse || '#FFFFFF'); + this.ray = FSS.Vector3.create(); +}; + +FSS.Light.prototype = Object.create(FSS.Object.prototype); + +/** + * @class Vertex + * @author Matthew Wagerfield + */ +FSS.Vertex = function(x, y, z) { + this.position = FSS.Vector3.create(x, y, z); +}; + +FSS.Vertex.prototype = { + setPosition: function(x, y, z) { + FSS.Vector3.set(this.position, x, y, z); + return this; + } +}; + +/** + * @class Triangle + * @author Matthew Wagerfield + */ +FSS.Triangle = function(a, b, c, s, material) { + this.a = a || new FSS.Vertex(); + this.b = b || new FSS.Vertex(); + this.c = c || new FSS.Vertex(); + this.vertices = [this.a, this.b, this.c]; + this.u = FSS.Vector3.create(); + this.v = FSS.Vector3.create(); + this.centroid = FSS.Vector3.create(); + this.normal = FSS.Vector3.create(); + this.material = material || new FSS.Material(); + this.color = new FSS.Color(); + this.polygon = s.polygon(); + this.polygon.attr({ + 'stroke-linejoin': 'round', + 'stroke-miterlimit': 1, + 'stroke-width': 1 + }); + + this.computeCentroid(); + this.computeNormal(); +}; + +FSS.Triangle.prototype = { + computeCentroid: function() { + this.centroid[0] = this.a.position[0] + this.b.position[0] + this.c.position[0]; + this.centroid[1] = this.a.position[1] + this.b.position[1] + this.c.position[1]; + this.centroid[2] = this.a.position[2] + this.b.position[2] + this.c.position[2]; + FSS.Vector3.divideScalar(this.centroid, 3); + return this; + }, + computeNormal: function() { + FSS.Vector3.subtractVectors(this.u, this.b.position, this.a.position); + FSS.Vector3.subtractVectors(this.v, this.c.position, this.a.position); + FSS.Vector3.crossVectors(this.normal, this.u, this.v); + FSS.Vector3.normalise(this.normal); + return this; + } +}; + +/** + * @class Geometry + * @author Matthew Wagerfield + */ +FSS.Geometry = function() { + this.vertices = []; + this.triangles = []; + this.dirty = false; +}; + +FSS.Geometry.prototype = { + update: function() { + if (this.dirty) { + var t,triangle; + for (t = this.triangles.length - 1; t >= 0; t--) { + triangle = this.triangles[t]; + triangle.computeCentroid(); + triangle.computeNormal(); + } + this.dirty = false; + } + return this; + } +}; + +/** + * @class Plane + * @author Matthew Wagerfield + */ +FSS.Plane = function(width, height, segments, slices, s, material) { + FSS.Geometry.call(this); + this.width = width || 100; + this.height = height || 100; + this.segments = segments || 4; + this.slices = slices || 4; + this.segmentWidth = this.width / this.segments; + this.sliceHeight = this.height / this.slices; + + // Cache Variables + var x, y, v0, v1, v2, v3, + vertex, triangle, vertices = [], + offsetX = this.width * -0.5, + offsetY = this.height * 0.5; + + // Add Vertices + for (x = 0; x <= this.segments; x++) { + vertices.push([]); + for (y = 0; y <= this.slices; y++) { + vertex = new FSS.Vertex(offsetX + x*this.segmentWidth, offsetY - y*this.sliceHeight); + vertices[x].push(vertex); + this.vertices.push(vertex); + } + } + + // Add Triangles + for (x = 0; x < this.segments; x++) { + for (y = 0; y < this.slices; y++) { + v0 = vertices[x+0][y+0]; + v1 = vertices[x+0][y+1]; + v2 = vertices[x+1][y+0]; + v3 = vertices[x+1][y+1]; + t0 = new FSS.Triangle(v0, v1, v2, s, material); + t1 = new FSS.Triangle(v2, v1, v3, s, material); + this.triangles.push(t0, t1); + } + } +}; + +FSS.Plane.prototype = Object.create(FSS.Geometry.prototype); + +/** + * @class Material + * @author Matthew Wagerfield + */ +FSS.Material = function(ambient, diffuse) { + this.ambient = new FSS.Color(ambient || '#444444'); + this.diffuse = new FSS.Color(diffuse || '#FFFFFF'); + this.slave = new FSS.Color(); +}; + +/** + * @class Mesh + * @author Matthew Wagerfield + */ +FSS.Mesh = function(geometry, material) { + FSS.Object.call(this); + this.geometry = geometry || new FSS.Geometry(); + this.material = material || new FSS.Material(); + this.side = FSS.FRONT; + this.visible = true; +}; + +FSS.Mesh.prototype = Object.create(FSS.Object.prototype); + +FSS.Mesh.prototype.update = function(lights, calculate) { + var t,triangle, l,light, illuminance; + + // Update Geometry + this.geometry.update(); + + // Calculate the triangle colors + if (calculate) { + + // Iterate through Triangles + for (t = this.geometry.triangles.length - 1; t >= 0; t--) { + triangle = this.geometry.triangles[t]; + + // Reset Triangle Color + FSS.Vector4.set(triangle.color.rgba); + + // Iterate through Lights + for (l = lights.length - 1; l >= 0; l--) { + light = lights[l]; + + // Calculate Illuminance + FSS.Vector3.subtractVectors(light.ray, light.position, triangle.centroid); + FSS.Vector3.normalise(light.ray); + illuminance = FSS.Vector3.dot(triangle.normal, light.ray); + if (this.side === FSS.FRONT) { + illuminance = Math.max(illuminance, 0); + } else if (this.side === FSS.BACK) { + illuminance = Math.abs(Math.min(illuminance, 0)); + } else if (this.side === FSS.DOUBLE) { + illuminance = Math.max(Math.abs(illuminance), 0); + } + + // Calculate Ambient Light + FSS.Vector4.multiplyVectors(triangle.material.slave.rgba, triangle.material.ambient.rgba, light.ambient.rgba); + FSS.Vector4.add(triangle.color.rgba, triangle.material.slave.rgba); + + // Calculate Diffuse Light + FSS.Vector4.multiplyVectors(triangle.material.slave.rgba, triangle.material.diffuse.rgba, light.diffuse.rgba); + FSS.Vector4.multiplyScalar(triangle.material.slave.rgba, illuminance); + FSS.Vector4.add(triangle.color.rgba, triangle.material.slave.rgba); + } + + // Clamp & Format Color + FSS.Vector4.clamp(triangle.color.rgba, 0, 1); + } + } + return this; +}; + +/** + * @class Scene + * @author Matthew Wagerfield + */ +FSS.Scene = function() { + this.meshes = []; + this.lights = []; +}; + +FSS.Scene.prototype = { + add: function(object) { + if (object instanceof FSS.Mesh && !~this.meshes.indexOf(object)) { + this.meshes.push(object); + } else if (object instanceof FSS.Light && !~this.lights.indexOf(object)) { + this.lights.push(object); + } + return this; + }, + remove: function(object) { + if (object instanceof FSS.Mesh && ~this.meshes.indexOf(object)) { + this.meshes.splice(this.meshes.indexOf(object), 1); + } else if (object instanceof FSS.Light && ~this.lights.indexOf(object)) { + this.lights.splice(this.lights.indexOf(object), 1); + } + return this; + } +}; + +/** + * @class Renderer + * @author Matthew Wagerfield + */ +FSS.Renderer = function() { + this.width = 0; + this.height = 0; + this.halfWidth = 0; + this.halfHeight = 0; +}; + +FSS.Renderer.prototype = { + setSize: function(width, height) { + if (this.width === width && this.height === height) return; + this.width = width; + this.height = height; + this.halfWidth = this.width * 0.5; + this.halfHeight = this.height * 0.5; + return this; + }, + clear: function() { + return this; + }, + render: function(scene) { + return this; + } +}; + +/** + * @class SVG Renderer + * @author Matthew Wagerfield + */ +FSS.SVGRenderer = function(s) { + FSS.Renderer.call(this); + this.element = s.g(); +}; + +FSS.SVGRenderer.prototype = Object.create(FSS.Renderer.prototype); + +FSS.SVGRenderer.prototype.setSize = function(width, height) { + FSS.Renderer.prototype.setSize.call(this, width, height); + return this; +}; + +FSS.SVGRenderer.prototype.clear = function() { + FSS.Renderer.prototype.clear.call(this); + for (var i = this.element.childNodes.length - 1; i >= 0; i--) { + this.element.removeChild(this.element.childNodes[i]); + } + return this; +}; + +FSS.SVGRenderer.prototype.render = function(scene) { + FSS.Renderer.prototype.render.call(this, scene); + var m,mesh, t,triangle, points, style; + + // Update Meshes + for (m = scene.meshes.length - 1; m >= 0; m--) { + mesh = scene.meshes[m]; + if (mesh.visible) { + mesh.update(scene.lights, true); + + // Render Triangles + for (t = mesh.geometry.triangles.length - 1; t >= 0; t--) { + triangle = mesh.geometry.triangles[t]; + + if (triangle.polygon.parent() !== this.element) { + this.element.append(triangle.polygon); + } + + points = this.formatPoint(triangle.a)+' '; + points += this.formatPoint(triangle.b)+' '; + points += this.formatPoint(triangle.c); + style = this.formatStyle(triangle.color.format()); + + triangle.polygon.attr({ + points: points, + style: style + }); + } + } + } + return this; +}; + +FSS.SVGRenderer.prototype.formatPoint = function(vertex) { + return (this.halfWidth+vertex.position[0])+','+(this.halfHeight-vertex.position[1]); +}; + +FSS.SVGRenderer.prototype.formatStyle = function(color) { + var style = 'fill:'+color+';'; + style += 'stroke:'+color+';'; + return style; +}; + +define("vendor/fss", function(){}); + +define('app/mesh',['require','vendor/fss'],function (require) { + + require('vendor/fss'); + + var Mesh = function (s, container, colorA, colorB) { + var instance = this, + _width = 440, + _height = 440, + now, + start = Date.now(), + renderer, + scene, + geometry, + material, + mesh, + light; + + instance.animating = false; + + instance.init = function () { + renderer = new FSS.SVGRenderer(s); + renderer.setSize(_width, _height); + renderer.element.transform('translate(-20, -20)'); //keep edges from showing + + instance.el = renderer.element; + + container.append(renderer.element); + + scene = new FSS.Scene(); + material = new FSS.Material(colorA, colorB); + geometry = new FSS.Plane(_width, _height, 10, 10, s, material); + mesh = new FSS.Mesh(geometry, material); + scene.add(mesh); + + light = new FSS.Light('#eeeeee', '#eeeeee'); + light.setPosition(300*Math.sin(0.001), 200*Math.cos(0.0005), 100); + scene.add(light); + + now = Date.now() - start; + + tweakMesh(); + distortMesh(); + renderer.render(scene); + } + + instance.start = function () { + instance.animating = true; + animate(); + } + + instance.stop = function () { + instance.animating = false; + } + + instance.setColor = function (colorA, colorB) { + var i; + + material = new FSS.Material(colorA, colorB); + + for (i = geometry.triangles.length - 1; i > -1; i -= 1) { + geometry.triangles[i].material = material; + } + + animate(); + } + + instance.rippleColor = function (colorA, colorB) { + var i; + + material = new FSS.Material(colorA, colorB); + + function colorTriangle(j) { + geometry.triangles[j].material = material; + + if (j == 0) { + setTimeout(function () { + animate(); + }, 10); //force clear + } + } + + for (i = geometry.triangles.length - 1; i > -1; i -= 1) { + var speed = 200 + Math.sin(0.1 + Math.abs(geometry.triangles[i].centroid[0] / geometry.triangles[i].centroid[1])) * 100; + setTimeout(colorTriangle, speed * 2, i); + } + } + + + function tweakMesh() { + var v, vertex; + + for (v = geometry.vertices.length - 1; v >= 0; v--) { + vertex = geometry.vertices[v]; + vertex.anchor = FSS.Vector3.clone(vertex.position); + vertex.step = FSS.Vector3.create( + Math.randomInRange(0.2, 1.0), + Math.randomInRange(0.2, 1.0), + Math.randomInRange(0.2, 1.0) + ); + vertex.time = Math.randomInRange(0, Math.PIM2); + } + } + + function distortMesh() { + var v, + vertex, + ox, oy, oz, + offset = 10 / 2; + + for (v = geometry.vertices.length - 1; v >= 0; v--) { + vertex = geometry.vertices[v]; + ox = Math.sin(vertex.time + vertex.step[0] * now * 0.002); + oy = Math.cos(vertex.time + vertex.step[1] * now * 0.002); + oz = Math.sin(vertex.time + vertex.step[2] * now * 0.002); + FSS.Vector3.set(vertex.position, + 0.2 * geometry.segmentWidth * ox, + 0.1 * geometry.sliceHeight * oy, + 0.7 * offset * oz - offset); + FSS.Vector3.add(vertex.position, vertex.anchor); + } + + geometry.dirty = true; + } + + function animate() { + now = Date.now() - start; + + if (mobilecheck() !== true) { + distortMesh(); + } + + renderer.render(scene); + + if (instance.animating !== false) { + requestAnimationFrame(animate); + } + } + + instance.init(); + } + + return Mesh; +}); +define('app/logo',['require'],function (require) { + + var Logo = function (s) { + var instance = this, + logo, + parts = [ + ['top', 0, 20], + ['left', 20, 0], + ['bottom', 0, -20], + ['right', -20, 0] + ], + components = [], + i = 0, + k = 0, + isLogoAnimated = false, + isCrocAnimated = false, + isCroc2Animated = false; + + logo = s.select("#snap-logo"); + + for (i = 0; i < parts.length; i++) { + var el = parts[i] + elid = el[0]; + element = logo.select("#snap-logo-" + elid); + element.attr({opacity:0, transform: "t" + (el[1]) + "," + (el[2])}); + components.push(element); + } + + function animateEach() { + if (!components[k]) { + return; + } + components[k].animate({ + transform: "t" + (0) + "," + (0), + opacity: 1 + }, 250, mina.easeout); + setTimeout(animateEach, 150); + k++; + }; + + this.animate = function () { + setTimeout(animateEach, 150); + } + + this.show = function () { + var i; + + for (i = 0; i < components.length; i += 1) { + components[i].attr({ + transform: "t" + (0) + "," + (0), + opacity: 1 + }); + } + + } + } + + return Logo; +}); +define('app/app',['require','snap','app/heart','app/device','app/burst','app/mesh','app/logo'],function (require) { + + require('snap'); + + var App, + Heart = require('app/heart'), + Device = require('app/device'), + Burst = require('app/burst'); + Mesh = require('app/mesh'); + Logo = require('app/logo'); + + App = function () { + var instance = this; + + this.started = false; + + this.init = function () { + var timeline, + ad, + s, + cover, + device, + heart, + burst, + screen1, + text1, + text2, + text3, + text4, + resolveScreen, + logo, + meshA, + meshAContainer, + replaycount = 0, + WIDTH = 400, + HEIGHT = 400, + WHITE = "#ffffff", + GREEN = "#09ae8a"; + + this.started = true; + + ad = document.getElementById('ad'); + s = new Snap("#ad"); + cover = s.select('#cover'); + meshAContainer = s.select('#meshAContainer'); + screen1 = s.select('#screen1'); + text1 = s.select('#text1'); + text2 = s.select('#text2'); + text3 = s.select('#text3'); + text4 = s.select('#text4'); + replayBtn = s.select('#replay-btn'); + resolveScreen = s.select('#resolve'); + logo = new Logo(s); + + handle_RESIZE(); + window.addEventListener('resize', handle_RESIZE); + ad.addEventListener('click', handle_CLICK); + replayBtn.click(replay_CLICK); + + addMeshA(); + cover.remove(); + addHeart(); + addComputer(); + addBurst(); + + function addHeart() { + heart = new Heart(s, WIDTH / 2, HEIGHT / 2); + } + + function addComputer() { + device = new Device(s, WIDTH / 2, HEIGHT / 2); + device.setScreen(192, 112); + device.setBack(208, 148); + device.setScale(0.1); + text2.after(device.el); + } + + function addBurst() { + burst = new Burst(s); + } + + function addMeshA() { + meshA = new Mesh(s, meshAContainer, '#afafaf', '#afafaf'); + } + + function addMeshB() { + meshA.el.remove(); + meshB = new Mesh(s, meshBContainer, '#09ae8a', '#777777'); + } + + function showMeshB() { + if (mobilecheck() !== true) { + meshB.start(); + } + } + + function showComputer() { + text1.animate({y: 80}, 100); + text2.animate({y: 350}, 100); + device.animScale(10, 300, mina.bounce); + heart.animFill(WHITE); + } + + function toTablet() { + device.animRotation(-90); + device.animScreen(76, 100); + device.animBack(92, 132); + heart.animScale(0.5, 200); + } + + function toPhone() { + device.hideKeyboard(); + device.animScreen(48, 76); + device.animBack(56, 100); + heart.animScale(0.3); + } + + function rotate() { + device.animRotation(90); + heart.animScale(0.4); + } + + function zoom() { + meshA.stop(); + device.animScale(10, 600); + heart.animScale(4, 600); + burst.anim(); + } + + function greenMesh() { + + meshA.setColor('#09ae8a', '#777777'); + + if (mobilecheck() !== true) { + meshA.start(); + } + + device.animOpacity(0, 200); + screen1.animate({ + opacity: 0 + }, 100); + } + + function maskReveal() { + heart.mask(); + } + + function showText3() { + device.setScale(0.01); + text3.animate({ + opacity: 1 + }, 200); + } + + function hideText3() { + text3.animate({ + opacity: 0 + }, 200); + + if (mobilecheck() !== true) { + meshA.rippleColor('#afafaf', '#afafaf'); + } else { + meshA.setColor('#afafaf', '#afafaf'); + } + } + + function resolve() { + resolveScreen.animate({ + opacity: 1 + }, 200); + } + + function stop() { + logo.animate(); + meshA.stop(); + } + + function reset() { + resolveScreen.attr({ + opacity: 0 + }); + + screen1.attr({ + opacity: 1 + }); + + text1.attr({y: 130}); + text2.attr({y: 300}); + + heart.setScale(1); + heart.setFill('#0DAE8A'); + heart.unmask(); + device.setOpacity(1); + device.setScreen(192, 112); + device.setBack(208, 148); + device.showKeyboard(); + meshA.start(); + burst.reset(); + } + + function replay_CLICK(e) { + e.stopPropagation(); + + replaycount += 1; + ga('send', 'event', 'button', 'click', 'replay', replaycount); + reset(); + run(); + } + + function handle_CLICK(e) { + ga('send', 'event', 'button', 'click', 'ad'); + top.window.location.href = 'http://snapsvg.io/'; + } + + function handle_RESIZE() { + var _w = window.innerWidth, + scale = _w / 400; + + ad.style.webkitTransform = 'scale(' + scale + ')'; + ad.style.MozTransform = 'scale(' + scale + ')'; + ad.style.msTransform = 'scale(' + scale + ')'; + ad.style.oTransform = 'scale(' + scale + ')'; + ad.style.transform = 'scale(' + scale + ')'; + + } + + function run() { + if (mobilecheck() !== true) { + meshA.start(); + } + setTimeout(showComputer, 2000); + setTimeout(toPhone, 3000); + setTimeout(rotate, 4000); + setTimeout(toTablet, 5000); + setTimeout(zoom, 6000); + setTimeout(greenMesh, 6300); + setTimeout(maskReveal, 6700); + setTimeout(showText3, 7000); + setTimeout(hideText3, 10000); + setTimeout(resolve, 10500); + setTimeout(stop, 10900); + } + + function basic() { + screen1.attr({opacity: 0}); + heart.el.attr({opacity: 0}); + replayBtn.attr({opacity: 0}); + logo.show(); + text4.select('tspan').attr({opacity: 0}); + text4.select('tspan:nth-child(2)').attr({y: 120}); + resolveScreen.attr({opacity: 1}); + } + + if (window.replay !== true) { + replayBtn.attr({opacity: 0}); + } + + if (window.supported !== false) { + run(); + } else { + basic(); + } + + } + + } + + return App; +}); +/*global require*/ + +require.config({ + shim: { + + }, + paths: { + snap: 'vendor/snap.svg', + tweenlite: 'vendor/greensock/TweenLite', + timelinelite: 'vendor/greensock/TimelineLite' + } +}); + +/** +* check support +*/ +window.ua = navigator.userAgent.toLowerCase(); +window.isAndroid = ua.indexOf("android") > -1; +window.isSafari = ua.indexOf("safari") > -1 && ua.indexOf("chrome") === -1; + +function checkSVG() { + return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect; +} + +/** +* check mobile +*/ +window.mobilecheck = function() { + var check = false; + (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); + return check; +} + +function addFallback() { + var link, + img; + + link = document.createElement('a'); + link.href = "http://snapsvg.io/"; + document.body.appendChild(link); + + img = new Image(); + img.src = "backup.jpg"; + img.style.position = "absolute"; + img.style.top = "0"; + img.style.left = "0"; + img.width = "100%"; + link.appendChild(img); +} + +window.supported = true; +window.replay = true; + +require(['app/app'], function (App) { + + if (checkSVG() !== true) { + addFallback(); + return; + } + + if (isAndroid === true) { + window.supported = false; + } + + if (isSafari === true) { + window.replay = false; + } + + window.app = new App(); + //app.init(); //fired from font loading +}); + + + +/** +* font loading +*/ +WebFontConfig = { + google: { + families: ['Open+Sans:300:latin', 'Source+Sans+Pro::latin'] + }, + inactive: function () { + if (typeof(app) !== 'undefined' && app.started !== true) { + app.init(); + } + }, + fontactive: function(familyName, fvd) { + if (typeof(app) !== 'undefined' && familyName == 'Open Sans') { + if (app.started !== true) { + app.init(); + } + } + } +}; +define("main", function(){}); diff --git a/demos/snap-ad/site/js/vendor/modernizr.min.js b/demos/snap-ad/site/js/vendor/modernizr.min.js new file mode 100644 index 0000000..02fb48a --- /dev/null +++ b/demos/snap-ad/site/js/vendor/modernizr.min.js @@ -0,0 +1,4 @@ +/* Modernizr 2.7.1 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-shiv-cssclasses-load + */ +;window.Modernizr=function(a,b,c){function u(a){j.cssText=a}function v(a,b){return u(prefixes.join(a+";")+(b||""))}function w(a,b){return typeof a===b}function x(a,b){return!!~(""+a).indexOf(b)}function y(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:w(f,"function")?f.bind(d||b):f}return!1}var d="2.7.1",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m={},n={},o={},p=[],q=p.slice,r,s={}.hasOwnProperty,t;!w(s,"undefined")&&!w(s.call,"undefined")?t=function(a,b){return s.call(a,b)}:t=function(a,b){return b in a&&w(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=q.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(q.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(q.call(arguments)))};return e});for(var z in m)t(m,z)&&(r=z.toLowerCase(),e[r]=m[z](),p.push((e[r]?"":"no-")+r));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)t(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},u(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+p.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f -1; i -= 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop); + } + + function getOwn(obj, prop) { + return hasProp(obj, prop) && obj[prop]; + } + + /** + * Cycles over properties in an object and calls a function for each + * property value. If the function returns a truthy value, then the + * iteration is stopped. + */ + function eachProp(obj, func) { + var prop; + for (prop in obj) { + if (hasProp(obj, prop)) { + if (func(obj[prop], prop)) { + break; + } + } + } + } + + /** + * Simple function to mix in properties from source into target, + * but only if target does not already have a property of the same name. + */ + function mixin(target, source, force, deepStringMixin) { + if (source) { + eachProp(source, function (value, prop) { + if (force || !hasProp(target, prop)) { + if (deepStringMixin && typeof value !== 'string') { + if (!target[prop]) { + target[prop] = {}; + } + mixin(target[prop], value, force, deepStringMixin); + } else { + target[prop] = value; + } + } + }); + } + return target; + } + + //Similar to Function.prototype.bind, but the 'this' object is specified + //first, since it is easier to read/figure out what 'this' will be. + function bind(obj, fn) { + return function () { + return fn.apply(obj, arguments); + }; + } + + function scripts() { + return document.getElementsByTagName('script'); + } + + //Allow getting a global that expressed in + //dot notation, like 'a.b.c'. + function getGlobal(value) { + if (!value) { + return value; + } + var g = global; + each(value.split('.'), function (part) { + g = g[part]; + }); + return g; + } + + /** + * Constructs an error with a pointer to an URL with more information. + * @param {String} id the error ID that maps to an ID on a web page. + * @param {String} message human readable error. + * @param {Error} [err] the original error, if there is one. + * + * @returns {Error} + */ + function makeError(id, msg, err, requireModules) { + var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); + e.requireType = id; + e.requireModules = requireModules; + if (err) { + e.originalError = err; + } + return e; + } + + if (typeof define !== 'undefined') { + //If a define is already in play via another AMD loader, + //do not overwrite. + return; + } + + if (typeof requirejs !== 'undefined') { + if (isFunction(requirejs)) { + //Do not overwrite and existing requirejs instance. + return; + } + cfg = requirejs; + requirejs = undefined; + } + + //Allow for a require config object + if (typeof require !== 'undefined' && !isFunction(require)) { + //assume it is a config object. + cfg = require; + require = undefined; + } + + function newContext(contextName) { + var inCheckLoaded, Module, context, handlers, + checkLoadedTimeoutId, + config = { + //Defaults. Do not set a default for map + //config to speed up normalize(), which + //will run faster if there is no default. + waitSeconds: 7, + baseUrl: './', + paths: {}, + pkgs: {}, + shim: {}, + config: {} + }, + registry = {}, + //registry of just enabled modules, to speed + //cycle breaking code when lots of modules + //are registered, but not activated. + enabledRegistry = {}, + undefEvents = {}, + defQueue = [], + defined = {}, + urlFetched = {}, + requireCounter = 1, + unnormalizedCounter = 1; + + /** + * Trims the . and .. from an array of path segments. + * It will keep a leading path segment if a .. will become + * the first path segment, to help with module name lookups, + * which act like paths, but can be remapped. But the end result, + * all paths that use this function should look normalized. + * NOTE: this method MODIFIES the input array. + * @param {Array} ary the array of path segments. + */ + function trimDots(ary) { + var i, part; + for (i = 0; ary[i]; i += 1) { + part = ary[i]; + if (part === '.') { + ary.splice(i, 1); + i -= 1; + } else if (part === '..') { + if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { + //End of the line. Keep at least one non-dot + //path segment at the front so it can be mapped + //correctly to disk. Otherwise, there is likely + //no path mapping for a path starting with '..'. + //This can still fail, but catches the most reasonable + //uses of .. + break; + } else if (i > 0) { + ary.splice(i - 1, 2); + i -= 2; + } + } + } + } + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @param {Boolean} applyMap apply the map config to the value. Should + * only be done if this normalization is for a dependency ID. + * @returns {String} normalized name + */ + function normalize(name, baseName, applyMap) { + var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment, + foundMap, foundI, foundStarMap, starI, + baseParts = baseName && baseName.split('/'), + normalizedBaseParts = baseParts, + map = config.map, + starMap = map && map['*']; + + //Adjust any relative paths. + if (name && name.charAt(0) === '.') { + //If have a base name, try to normalize against it, + //otherwise, assume it is a top-level require that will + //be relative to baseUrl in the end. + if (baseName) { + if (getOwn(config.pkgs, baseName)) { + //If the baseName is a package name, then just treat it as one + //name to concat the name with. + normalizedBaseParts = baseParts = [baseName]; + } else { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); + } + + name = normalizedBaseParts.concat(name.split('/')); + trimDots(name); + + //Some use of packages may use a . path to reference the + //'main' module name, so normalize for that. + pkgConfig = getOwn(config.pkgs, (pkgName = name[0])); + name = name.join('/'); + if (pkgConfig && name === pkgName + '/' + pkgConfig.main) { + name = pkgName; + } + } else if (name.indexOf('./') === 0) { + // No baseName, so this is ID is resolved relative + // to baseUrl, pull off the leading dot. + name = name.substring(2); + } + } + + //Apply map config if available. + if (applyMap && map && (baseParts || starMap)) { + nameParts = name.split('/'); + + for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join('/'); + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = getOwn(mapValue, nameSegment); + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue; + foundI = i; + break; + } + } + } + } + + if (foundMap) { + break; + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { + foundStarMap = getOwn(starMap, nameSegment); + starI = i; + } + } + + if (!foundMap && foundStarMap) { + foundMap = foundStarMap; + foundI = starI; + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap); + name = nameParts.join('/'); + } + } + + return name; + } + + function removeScript(name) { + if (isBrowser) { + each(scripts(), function (scriptNode) { + if (scriptNode.getAttribute('data-requiremodule') === name && + scriptNode.getAttribute('data-requirecontext') === context.contextName) { + scriptNode.parentNode.removeChild(scriptNode); + return true; + } + }); + } + } + + function hasPathFallback(id) { + var pathConfig = getOwn(config.paths, id); + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { + removeScript(id); + //Pop off the first array value, since it failed, and + //retry + pathConfig.shift(); + context.require.undef(id); + context.require([id]); + return true; + } + } + + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1; + if (index > -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + return [prefix, name]; + } + + /** + * Creates a module mapping that includes plugin prefix, module + * name, and path. If parentModuleMap is provided it will + * also normalize the name via require.normalize() + * + * @param {String} name the module name + * @param {String} [parentModuleMap] parent module map + * for the module name, used to resolve relative names. + * @param {Boolean} isNormalized: is the ID already normalized. + * This is true if this call is done for a define() module ID. + * @param {Boolean} applyMap: apply the map config to the ID. + * Should only be true if this map is for a dependency. + * + * @returns {Object} + */ + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { + var url, pluginModule, suffix, nameParts, + prefix = null, + parentName = parentModuleMap ? parentModuleMap.name : null, + originalName = name, + isDefine = true, + normalizedName = ''; + + //If no name, then it means it is a require call, generate an + //internal name. + if (!name) { + isDefine = false; + name = '_@r' + (requireCounter += 1); + } + + nameParts = splitPrefix(name); + prefix = nameParts[0]; + name = nameParts[1]; + + if (prefix) { + prefix = normalize(prefix, parentName, applyMap); + pluginModule = getOwn(defined, prefix); + } + + //Account for relative paths if there is a base name. + if (name) { + if (prefix) { + if (pluginModule && pluginModule.normalize) { + //Plugin is loaded, use its normalize method. + normalizedName = pluginModule.normalize(name, function (name) { + return normalize(name, parentName, applyMap); + }); + } else { + normalizedName = normalize(name, parentName, applyMap); + } + } else { + //A regular module. + normalizedName = normalize(name, parentName, applyMap); + + //Normalized name may be a plugin ID due to map config + //application in normalize. The map config values must + //already be normalized, so do not need to redo that part. + nameParts = splitPrefix(normalizedName); + prefix = nameParts[0]; + normalizedName = nameParts[1]; + isNormalized = true; + + url = context.nameToUrl(normalizedName); + } + } + + //If the id is a plugin id that cannot be determined if it needs + //normalization, stamp it with a unique ID so two matching relative + //ids that may conflict can be separate. + suffix = prefix && !pluginModule && !isNormalized ? + '_unnormalized' + (unnormalizedCounter += 1) : + ''; + + return { + prefix: prefix, + name: normalizedName, + parentMap: parentModuleMap, + unnormalized: !!suffix, + url: url, + originalName: originalName, + isDefine: isDefine, + id: (prefix ? + prefix + '!' + normalizedName : + normalizedName) + suffix + }; + } + + function getModule(depMap) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (!mod) { + mod = registry[id] = new context.Module(depMap); + } + + return mod; + } + + function on(depMap, name, fn) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (hasProp(defined, id) && + (!mod || mod.defineEmitComplete)) { + if (name === 'defined') { + fn(defined[id]); + } + } else { + getModule(depMap).on(name, fn); + } + } + + function onError(err, errback) { + var ids = err.requireModules, + notified = false; + + if (errback) { + errback(err); + } else { + each(ids, function (id) { + var mod = getOwn(registry, id); + if (mod) { + //Set error on module, so it skips timeout checks. + mod.error = err; + if (mod.events.error) { + notified = true; + mod.emit('error', err); + } + } + }); + + if (!notified) { + req.onError(err); + } + } + } + + /** + * Internal method to transfer globalQueue items to this context's + * defQueue. + */ + function takeGlobalQueue() { + //Push all the globalDefQueue items into the context's defQueue + if (globalDefQueue.length) { + //Array splice in the values since the context code has a + //local var ref to defQueue, so cannot just reassign the one + //on context. + apsp.apply(defQueue, + [defQueue.length - 1, 0].concat(globalDefQueue)); + globalDefQueue = []; + } + } + + handlers = { + 'require': function (mod) { + if (mod.require) { + return mod.require; + } else { + return (mod.require = context.makeRequire(mod.map)); + } + }, + 'exports': function (mod) { + mod.usingExports = true; + if (mod.map.isDefine) { + if (mod.exports) { + return mod.exports; + } else { + return (mod.exports = defined[mod.map.id] = {}); + } + } + }, + 'module': function (mod) { + if (mod.module) { + return mod.module; + } else { + return (mod.module = { + id: mod.map.id, + uri: mod.map.url, + config: function () { + return (config.config && getOwn(config.config, mod.map.id)) || {}; + }, + exports: defined[mod.map.id] + }); + } + } + }; + + function cleanRegistry(id) { + //Clean up machinery used for waiting modules. + delete registry[id]; + delete enabledRegistry[id]; + } + + function breakCycle(mod, traced, processed) { + var id = mod.map.id; + + if (mod.error) { + mod.emit('error', mod.error); + } else { + traced[id] = true; + each(mod.depMaps, function (depMap, i) { + var depId = depMap.id, + dep = getOwn(registry, depId); + + //Only force things that have not completed + //being defined, so still in the registry, + //and only if it has not been matched up + //in the module already. + if (dep && !mod.depMatched[i] && !processed[depId]) { + if (getOwn(traced, depId)) { + mod.defineDep(i, defined[depId]); + mod.check(); //pass false? + } else { + breakCycle(dep, traced, processed); + } + } + }); + processed[id] = true; + } + } + + function checkLoaded() { + var map, modId, err, usingPathFallback, + waitInterval = config.waitSeconds * 1000, + //It is possible to disable the wait interval by using waitSeconds of 0. + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), + noLoads = [], + reqCalls = [], + stillLoading = false, + needCycleCheck = true; + + //Do not bother if this call was a result of a cycle break. + if (inCheckLoaded) { + return; + } + + inCheckLoaded = true; + + //Figure out the state of all the modules. + eachProp(enabledRegistry, function (mod) { + map = mod.map; + modId = map.id; + + //Skip things that are not enabled or in error state. + if (!mod.enabled) { + return; + } + + if (!map.isDefine) { + reqCalls.push(mod); + } + + if (!mod.error) { + //If the module should be executed, and it has not + //been inited and time is up, remember it. + if (!mod.inited && expired) { + if (hasPathFallback(modId)) { + usingPathFallback = true; + stillLoading = true; + } else { + noLoads.push(modId); + removeScript(modId); + } + } else if (!mod.inited && mod.fetched && map.isDefine) { + stillLoading = true; + if (!map.prefix) { + //No reason to keep looking for unfinished + //loading. If the only stillLoading is a + //plugin resource though, keep going, + //because it may be that a plugin resource + //is waiting on a non-plugin cycle. + return (needCycleCheck = false); + } + } + } + }); + + if (expired && noLoads.length) { + //If wait time expired, throw error of unloaded modules. + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); + err.contextName = context.contextName; + return onError(err); + } + + //Not expired, check for a cycle. + if (needCycleCheck) { + each(reqCalls, function (mod) { + breakCycle(mod, {}, {}); + }); + } + + //If still waiting on loads, and the waiting load is something + //other than a plugin resource, or there are still outstanding + //scripts, then just try back later. + if ((!expired || usingPathFallback) && stillLoading) { + //Something is still waiting to load. Wait for it, but only + //if a timeout is not already in effect. + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { + checkLoadedTimeoutId = setTimeout(function () { + checkLoadedTimeoutId = 0; + checkLoaded(); + }, 50); + } + } + + inCheckLoaded = false; + } + + Module = function (map) { + this.events = getOwn(undefEvents, map.id) || {}; + this.map = map; + this.shim = getOwn(config.shim, map.id); + this.depExports = []; + this.depMaps = []; + this.depMatched = []; + this.pluginMaps = {}; + this.depCount = 0; + + /* this.exports this.factory + this.depMaps = [], + this.enabled, this.fetched + */ + }; + + Module.prototype = { + init: function (depMaps, factory, errback, options) { + options = options || {}; + + //Do not do more inits if already done. Can happen if there + //are multiple define calls for the same module. That is not + //a normal, common case, but it is also not unexpected. + if (this.inited) { + return; + } + + this.factory = factory; + + if (errback) { + //Register for errors on this module. + this.on('error', errback); + } else if (this.events.error) { + //If no errback already, but there are error listeners + //on this module, set up an errback to pass to the deps. + errback = bind(this, function (err) { + this.emit('error', err); + }); + } + + //Do a copy of the dependency array, so that + //source inputs are not modified. For example + //"shim" deps are passed in here directly, and + //doing a direct modification of the depMaps array + //would affect that config. + this.depMaps = depMaps && depMaps.slice(0); + + this.errback = errback; + + //Indicate this module has be initialized + this.inited = true; + + this.ignore = options.ignore; + + //Could have option to init this module in enabled mode, + //or could have been previously marked as enabled. However, + //the dependencies are not known until init is called. So + //if enabled previously, now trigger dependencies as enabled. + if (options.enabled || this.enabled) { + //Enable this module and dependencies. + //Will call this.check() + this.enable(); + } else { + this.check(); + } + }, + + defineDep: function (i, depExports) { + //Because of cycles, defined callback for a given + //export can be called more than once. + if (!this.depMatched[i]) { + this.depMatched[i] = true; + this.depCount -= 1; + this.depExports[i] = depExports; + } + }, + + fetch: function () { + if (this.fetched) { + return; + } + this.fetched = true; + + context.startTime = (new Date()).getTime(); + + var map = this.map; + + //If the manager is for a plugin managed resource, + //ask the plugin to load it now. + if (this.shim) { + context.makeRequire(this.map, { + enableBuildCallback: true + })(this.shim.deps || [], bind(this, function () { + return map.prefix ? this.callPlugin() : this.load(); + })); + } else { + //Regular dependency. + return map.prefix ? this.callPlugin() : this.load(); + } + }, + + load: function () { + var url = this.map.url; + + //Regular dependency. + if (!urlFetched[url]) { + urlFetched[url] = true; + context.load(this.map.id, url); + } + }, + + /** + * Checks if the module is ready to define itself, and if so, + * define it. + */ + check: function () { + if (!this.enabled || this.enabling) { + return; + } + + var err, cjsModule, + id = this.map.id, + depExports = this.depExports, + exports = this.exports, + factory = this.factory; + + if (!this.inited) { + this.fetch(); + } else if (this.error) { + this.emit('error', this.error); + } else if (!this.defining) { + //The factory could trigger another require call + //that would result in checking this module to + //define itself again. If already in the process + //of doing that, skip this work. + this.defining = true; + + if (this.depCount < 1 && !this.defined) { + if (isFunction(factory)) { + //If there is an error listener, favor passing + //to that instead of throwing an error. + if (this.events.error) { + try { + exports = context.execCb(id, factory, depExports, exports); + } catch (e) { + err = e; + } + } else { + exports = context.execCb(id, factory, depExports, exports); + } + + if (this.map.isDefine) { + //If setting exports via 'module' is in play, + //favor that over return value and exports. After that, + //favor a non-undefined return value over exports use. + cjsModule = this.module; + if (cjsModule && + cjsModule.exports !== undefined && + //Make sure it is not already the exports value + cjsModule.exports !== this.exports) { + exports = cjsModule.exports; + } else if (exports === undefined && this.usingExports) { + //exports already set the defined value. + exports = this.exports; + } + } + + if (err) { + err.requireMap = this.map; + err.requireModules = [this.map.id]; + err.requireType = 'define'; + return onError((this.error = err)); + } + + } else { + //Just a literal value + exports = factory; + } + + this.exports = exports; + + if (this.map.isDefine && !this.ignore) { + defined[id] = exports; + + if (req.onResourceLoad) { + req.onResourceLoad(context, this.map, this.depMaps); + } + } + + //Clean up + cleanRegistry(id); + + this.defined = true; + } + + //Finished the define stage. Allow calling check again + //to allow define notifications below in the case of a + //cycle. + this.defining = false; + + if (this.defined && !this.defineEmitted) { + this.defineEmitted = true; + this.emit('defined', this.exports); + this.defineEmitComplete = true; + } + + } + }, + + callPlugin: function () { + var map = this.map, + id = map.id, + //Map already normalized the prefix. + pluginMap = makeModuleMap(map.prefix); + + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(pluginMap); + + on(pluginMap, 'defined', bind(this, function (plugin) { + var load, normalizedMap, normalizedMod, + name = this.map.name, + parentName = this.map.parentMap ? this.map.parentMap.name : null, + localRequire = context.makeRequire(map.parentMap, { + enableBuildCallback: true + }); + + //If current map is not normalized, wait for that + //normalized name to load instead of continuing. + if (this.map.unnormalized) { + //Normalize the ID if the plugin allows it. + if (plugin.normalize) { + name = plugin.normalize(name, function (name) { + return normalize(name, parentName, true); + }) || ''; + } + + //prefix and name should already be normalized, no need + //for applying map config again either. + normalizedMap = makeModuleMap(map.prefix + '!' + name, + this.map.parentMap); + on(normalizedMap, + 'defined', bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true, + ignore: true + }); + })); + + normalizedMod = getOwn(registry, normalizedMap.id); + if (normalizedMod) { + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(normalizedMap); + + if (this.events.error) { + normalizedMod.on('error', bind(this, function (err) { + this.emit('error', err); + })); + } + normalizedMod.enable(); + } + + return; + } + + load = bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true + }); + }); + + load.error = bind(this, function (err) { + this.inited = true; + this.error = err; + err.requireModules = [id]; + + //Remove temp unnormalized modules for this module, + //since they will never be resolved otherwise now. + eachProp(registry, function (mod) { + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { + cleanRegistry(mod.map.id); + } + }); + + onError(err); + }); + + //Allow plugins to load other code without having to know the + //context or how to 'complete' the load. + load.fromText = bind(this, function (text, textAlt) { + /*jslint evil: true */ + var moduleName = map.name, + moduleMap = makeModuleMap(moduleName), + hasInteractive = useInteractive; + + //As of 2.1.0, support just passing the text, to reinforce + //fromText only being called once per resource. Still + //support old style of passing moduleName but discard + //that moduleName in favor of the internal ref. + if (textAlt) { + text = textAlt; + } + + //Turn off interactive script matching for IE for any define + //calls in the text, then turn it back on at the end. + if (hasInteractive) { + useInteractive = false; + } + + //Prime the system by creating a module instance for + //it. + getModule(moduleMap); + + //Transfer any config to this other module. + if (hasProp(config.config, id)) { + config.config[moduleName] = config.config[id]; + } + + try { + req.exec(text); + } catch (e) { + return onError(makeError('fromtexteval', + 'fromText eval for ' + id + + ' failed: ' + e, + e, + [id])); + } + + if (hasInteractive) { + useInteractive = true; + } + + //Mark this as a dependency for the plugin + //resource + this.depMaps.push(moduleMap); + + //Support anonymous modules. + context.completeLoad(moduleName); + + //Bind the value of that module to the value for this + //resource ID. + localRequire([moduleName], load); + }); + + //Use parentName here since the plugin's name is not reliable, + //could be some weird string with no path that actually wants to + //reference the parentName's path. + plugin.load(map.name, localRequire, load, config); + })); + + context.enable(pluginMap, this); + this.pluginMaps[pluginMap.id] = pluginMap; + }, + + enable: function () { + enabledRegistry[this.map.id] = this; + this.enabled = true; + + //Set flag mentioning that the module is enabling, + //so that immediate calls to the defined callbacks + //for dependencies do not trigger inadvertent load + //with the depCount still being zero. + this.enabling = true; + + //Enable each dependency + each(this.depMaps, bind(this, function (depMap, i) { + var id, mod, handler; + + if (typeof depMap === 'string') { + //Dependency needs to be converted to a depMap + //and wired up to this module. + depMap = makeModuleMap(depMap, + (this.map.isDefine ? this.map : this.map.parentMap), + false, + !this.skipMap); + this.depMaps[i] = depMap; + + handler = getOwn(handlers, depMap.id); + + if (handler) { + this.depExports[i] = handler(this); + return; + } + + this.depCount += 1; + + on(depMap, 'defined', bind(this, function (depExports) { + this.defineDep(i, depExports); + this.check(); + })); + + if (this.errback) { + on(depMap, 'error', this.errback); + } + } + + id = depMap.id; + mod = registry[id]; + + //Skip special modules like 'require', 'exports', 'module' + //Also, don't call enable if it is already enabled, + //important in circular dependency cases. + if (!hasProp(handlers, id) && mod && !mod.enabled) { + context.enable(depMap, this); + } + })); + + //Enable each plugin that is used in + //a dependency + eachProp(this.pluginMaps, bind(this, function (pluginMap) { + var mod = getOwn(registry, pluginMap.id); + if (mod && !mod.enabled) { + context.enable(pluginMap, this); + } + })); + + this.enabling = false; + + this.check(); + }, + + on: function (name, cb) { + var cbs = this.events[name]; + if (!cbs) { + cbs = this.events[name] = []; + } + cbs.push(cb); + }, + + emit: function (name, evt) { + each(this.events[name], function (cb) { + cb(evt); + }); + if (name === 'error') { + //Now that the error handler was triggered, remove + //the listeners, since this broken Module instance + //can stay around for a while in the registry. + delete this.events[name]; + } + } + }; + + function callGetModule(args) { + //Skip modules already defined. + if (!hasProp(defined, args[0])) { + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); + } + } + + function removeListener(node, func, name, ieName) { + //Favor detachEvent because of IE9 + //issue, see attachEvent/addEventListener comment elsewhere + //in this file. + if (node.detachEvent && !isOpera) { + //Probably IE. If not it will throw an error, which will be + //useful to know. + if (ieName) { + node.detachEvent(ieName, func); + } + } else { + node.removeEventListener(name, func, false); + } + } + + /** + * Given an event from a script node, get the requirejs info from it, + * and then removes the event listeners on the node. + * @param {Event} evt + * @returns {Object} + */ + function getScriptData(evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + var node = evt.currentTarget || evt.srcElement; + + //Remove the listeners once here. + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); + removeListener(node, context.onScriptError, 'error'); + + return { + node: node, + id: node && node.getAttribute('data-requiremodule') + }; + } + + function intakeDefines() { + var args; + + //Any defined modules in the global queue, intake them now. + takeGlobalQueue(); + + //Make sure any remaining defQueue items get properly processed. + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); + } else { + //args are id, deps, factory. Should be normalized by the + //define() function. + callGetModule(args); + } + } + } + + context = { + config: config, + contextName: contextName, + registry: registry, + defined: defined, + urlFetched: urlFetched, + defQueue: defQueue, + Module: Module, + makeModuleMap: makeModuleMap, + nextTick: req.nextTick, + onError: onError, + + /** + * Set a configuration for the context. + * @param {Object} cfg config object to integrate. + */ + configure: function (cfg) { + //Make sure the baseUrl ends in a slash. + if (cfg.baseUrl) { + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { + cfg.baseUrl += '/'; + } + } + + //Save off the paths and packages since they require special processing, + //they are additive. + var pkgs = config.pkgs, + shim = config.shim, + objs = { + paths: true, + config: true, + map: true + }; + + eachProp(cfg, function (value, prop) { + if (objs[prop]) { + if (prop === 'map') { + if (!config.map) { + config.map = {}; + } + mixin(config[prop], value, true, true); + } else { + mixin(config[prop], value, true); + } + } else { + config[prop] = value; + } + }); + + //Merge shim + if (cfg.shim) { + eachProp(cfg.shim, function (value, id) { + //Normalize the structure + if (isArray(value)) { + value = { + deps: value + }; + } + if ((value.exports || value.init) && !value.exportsFn) { + value.exportsFn = context.makeShimExports(value); + } + shim[id] = value; + }); + config.shim = shim; + } + + //Adjust packages if necessary. + if (cfg.packages) { + each(cfg.packages, function (pkgObj) { + var location; + + pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; + location = pkgObj.location; + + //Create a brand new object on pkgs, since currentPackages can + //be passed in again, and config.pkgs is the internal transformed + //state for all package configs. + pkgs[pkgObj.name] = { + name: pkgObj.name, + location: location || pkgObj.name, + //Remove leading dot in main, so main paths are normalized, + //and remove any trailing .js, since different package + //envs have different conventions: some use a module name, + //some use a file name. + main: (pkgObj.main || 'main') + .replace(currDirRegExp, '') + .replace(jsSuffixRegExp, '') + }; + }); + + //Done with modifications, assing packages back to context config + config.pkgs = pkgs; + } + + //If there are any "waiting to execute" modules in the registry, + //update the maps for them, since their info, like URLs to load, + //may have changed. + eachProp(registry, function (mod, id) { + //If module already has init called, since it is too + //late to modify them, and ignore unnormalized ones + //since they are transient. + if (!mod.inited && !mod.map.unnormalized) { + mod.map = makeModuleMap(id); + } + }); + + //If a deps array or a config callback is specified, then call + //require with those args. This is useful when require is defined as a + //config object before require.js is loaded. + if (cfg.deps || cfg.callback) { + context.require(cfg.deps || [], cfg.callback); + } + }, + + makeShimExports: function (value) { + function fn() { + var ret; + if (value.init) { + ret = value.init.apply(global, arguments); + } + return ret || (value.exports && getGlobal(value.exports)); + } + return fn; + }, + + makeRequire: function (relMap, options) { + options = options || {}; + + function localRequire(deps, callback, errback) { + var id, map, requireMod; + + if (options.enableBuildCallback && callback && isFunction(callback)) { + callback.__requireJsBuild = true; + } + + if (typeof deps === 'string') { + if (isFunction(callback)) { + //Invalid call + return onError(makeError('requireargs', 'Invalid require call'), errback); + } + + //If require|exports|module are requested, get the + //value for them from the special handlers. Caveat: + //this only works while module is being defined. + if (relMap && hasProp(handlers, deps)) { + return handlers[deps](registry[relMap.id]); + } + + //Synchronous access to one module. If require.get is + //available (as in the Node adapter), prefer that. + if (req.get) { + return req.get(context, deps, relMap, localRequire); + } + + //Normalize module name, if it contains . or .. + map = makeModuleMap(deps, relMap, false, true); + id = map.id; + + if (!hasProp(defined, id)) { + return onError(makeError('notloaded', 'Module name "' + + id + + '" has not been loaded yet for context: ' + + contextName + + (relMap ? '' : '. Use require([])'))); + } + return defined[id]; + } + + //Grab defines waiting in the global queue. + intakeDefines(); + + //Mark all the dependencies as needing to be loaded. + context.nextTick(function () { + //Some defines could have been added since the + //require call, collect them. + intakeDefines(); + + requireMod = getModule(makeModuleMap(null, relMap)); + + //Store if map config should be applied to this require + //call for dependencies. + requireMod.skipMap = options.skipMap; + + requireMod.init(deps, callback, errback, { + enabled: true + }); + + checkLoaded(); + }); + + return localRequire; + } + + mixin(localRequire, { + isBrowser: isBrowser, + + /** + * Converts a module name + .extension into an URL path. + * *Requires* the use of a module name. It does not support using + * plain URLs like nameToUrl. + */ + toUrl: function (moduleNamePlusExt) { + var ext, + index = moduleNamePlusExt.lastIndexOf('.'), + segment = moduleNamePlusExt.split('/')[0], + isRelative = segment === '.' || segment === '..'; + + //Have a file extension alias, and it is not the + //dots from a relative path. + if (index !== -1 && (!isRelative || index > 1)) { + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); + } + + return context.nameToUrl(normalize(moduleNamePlusExt, + relMap && relMap.id, true), ext, true); + }, + + defined: function (id) { + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); + }, + + specified: function (id) { + id = makeModuleMap(id, relMap, false, true).id; + return hasProp(defined, id) || hasProp(registry, id); + } + }); + + //Only allow undef on top level require calls + if (!relMap) { + localRequire.undef = function (id) { + //Bind any waiting define() calls to this context, + //fix for #408 + takeGlobalQueue(); + + var map = makeModuleMap(id, relMap, true), + mod = getOwn(registry, id); + + delete defined[id]; + delete urlFetched[map.url]; + delete undefEvents[id]; + + if (mod) { + //Hold on to listeners in case the + //module will be attempted to be reloaded + //using a different config. + if (mod.events.defined) { + undefEvents[id] = mod.events; + } + + cleanRegistry(id); + } + }; + } + + return localRequire; + }, + + /** + * Called to enable a module if it is still in the registry + * awaiting enablement. A second arg, parent, the parent module, + * is passed in for context, when this method is overriden by + * the optimizer. Not shown here to keep code compact. + */ + enable: function (depMap) { + var mod = getOwn(registry, depMap.id); + if (mod) { + getModule(depMap).enable(); + } + }, + + /** + * Internal method used by environment adapters to complete a load event. + * A load event could be a script load or just a load pass from a synchronous + * load call. + * @param {String} moduleName the name of the module to potentially complete. + */ + completeLoad: function (moduleName) { + var found, args, mod, + shim = getOwn(config.shim, moduleName) || {}, + shExports = shim.exports; + + takeGlobalQueue(); + + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + args[0] = moduleName; + //If already found an anonymous module and bound it + //to this name, then this is some other anon module + //waiting for its completeLoad to fire. + if (found) { + break; + } + found = true; + } else if (args[0] === moduleName) { + //Found matching define call for this script! + found = true; + } + + callGetModule(args); + } + + //Do this after the cycle of callGetModule in case the result + //of those calls/init calls changes the registry. + mod = getOwn(registry, moduleName); + + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { + if (hasPathFallback(moduleName)) { + return; + } else { + return onError(makeError('nodefine', + 'No define call for ' + moduleName, + null, + [moduleName])); + } + } else { + //A script that does not call define(), so just simulate + //the call for it. + callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); + } + } + + checkLoaded(); + }, + + /** + * Converts a module name to a file path. Supports cases where + * moduleName may actually be just an URL. + * Note that it **does not** call normalize on the moduleName, + * it is assumed to have already been normalized. This is an + * internal API, not a public one. Use toUrl for the public API. + */ + nameToUrl: function (moduleName, ext, skipExt) { + var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, + parentPath; + + //If a colon is in the URL, it indicates a protocol is used and it is just + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) + //or ends with .js, then assume the user meant to use an url and not a module id. + //The slash is important for protocol-less URLs as well as full paths. + if (req.jsExtRegExp.test(moduleName)) { + //Just a plain path, not module name lookup, so just return it. + //Add extension if it is included. This is a bit wonky, only non-.js things pass + //an extension, this method probably needs to be reworked. + url = moduleName + (ext || ''); + } else { + //A module that needs to be converted to a path. + paths = config.paths; + pkgs = config.pkgs; + + syms = moduleName.split('/'); + //For each module name segment, see if there is a path + //registered for it. Start with most specific name + //and work up from it. + for (i = syms.length; i > 0; i -= 1) { + parentModule = syms.slice(0, i).join('/'); + pkg = getOwn(pkgs, parentModule); + parentPath = getOwn(paths, parentModule); + if (parentPath) { + //If an array, it means there are a few choices, + //Choose the one that is desired + if (isArray(parentPath)) { + parentPath = parentPath[0]; + } + syms.splice(0, i, parentPath); + break; + } else if (pkg) { + //If module name is just the package name, then looking + //for the main module. + if (moduleName === pkg.name) { + pkgPath = pkg.location + '/' + pkg.main; + } else { + pkgPath = pkg.location; + } + syms.splice(0, i, pkgPath); + break; + } + } + + //Join the path parts together, then figure out if baseUrl is needed. + url = syms.join('/'); + url += (ext || (/\?/.test(url) || skipExt ? '' : '.js')); + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; + } + + return config.urlArgs ? url + + ((url.indexOf('?') === -1 ? '?' : '&') + + config.urlArgs) : url; + }, + + //Delegates to req.load. Broken out as a separate function to + //allow overriding in the optimizer. + load: function (id, url) { + req.load(context, id, url); + }, + + /** + * Executes a module callack function. Broken out as a separate function + * solely to allow the build system to sequence the files in the built + * layer in the right sequence. + * + * @private + */ + execCb: function (name, callback, args, exports) { + return callback.apply(exports, args); + }, + + /** + * callback for script loads, used to check status of loading. + * + * @param {Event} evt the event from the browser for the script + * that was loaded. + */ + onScriptLoad: function (evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + if (evt.type === 'load' || + (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { + //Reset interactive script so a script node is not held onto for + //to long. + interactiveScript = null; + + //Pull out the name of the module and the context. + var data = getScriptData(evt); + context.completeLoad(data.id); + } + }, + + /** + * Callback for script errors. + */ + onScriptError: function (evt) { + var data = getScriptData(evt); + if (!hasPathFallback(data.id)) { + return onError(makeError('scripterror', 'Script error', evt, [data.id])); + } + } + }; + + context.require = context.makeRequire(); + return context; + } + + /** + * Main entry point. + * + * If the only argument to require is a string, then the module that + * is represented by that string is fetched for the appropriate context. + * + * If the first argument is an array, then it will be treated as an array + * of dependency string names to fetch. An optional function callback can + * be specified to execute when all of those dependencies are available. + * + * Make a local req variable to help Caja compliance (it assumes things + * on a require that are not standardized), and to give a short + * name for minification/local scope use. + */ + req = requirejs = function (deps, callback, errback, optional) { + + //Find the right context, use default + var context, config, + contextName = defContextName; + + // Determine if have config object in the call. + if (!isArray(deps) && typeof deps !== 'string') { + // deps is a config object + config = deps; + if (isArray(callback)) { + // Adjust args if there are dependencies + deps = callback; + callback = errback; + errback = optional; + } else { + deps = []; + } + } + + if (config && config.context) { + contextName = config.context; + } + + context = getOwn(contexts, contextName); + if (!context) { + context = contexts[contextName] = req.s.newContext(contextName); + } + + if (config) { + context.configure(config); + } + + return context.require(deps, callback, errback); + }; + + /** + * Support require.config() to make it easier to cooperate with other + * AMD loaders on globally agreed names. + */ + req.config = function (config) { + return req(config); + }; + + /** + * Execute something after the current tick + * of the event loop. Override for other envs + * that have a better solution than setTimeout. + * @param {Function} fn function to execute later. + */ + req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { + setTimeout(fn, 4); + } : function (fn) { fn(); }; + + /** + * Export require as a global, but only if it does not already exist. + */ + if (!require) { + require = req; + } + + req.version = version; + + //Used to filter out dependencies that are already paths. + req.jsExtRegExp = /^\/|:|\?|\.js$/; + req.isBrowser = isBrowser; + s = req.s = { + contexts: contexts, + newContext: newContext + }; + + //Create default context. + req({}); + + //Exports some context-sensitive methods on global require. + each([ + 'toUrl', + 'undef', + 'defined', + 'specified' + ], function (prop) { + //Reference from contexts instead of early binding to default context, + //so that during builds, the latest instance of the default context + //with its config gets used. + req[prop] = function () { + var ctx = contexts[defContextName]; + return ctx.require[prop].apply(ctx, arguments); + }; + }); + + if (isBrowser) { + head = s.head = document.getElementsByTagName('head')[0]; + //If BASE tag is in play, using appendChild is a problem for IE6. + //When that browser dies, this can be removed. Details in this jQuery bug: + //http://dev.jquery.com/ticket/2709 + baseElement = document.getElementsByTagName('base')[0]; + if (baseElement) { + head = s.head = baseElement.parentNode; + } + } + + /** + * Any errors that require explicitly generates will be passed to this + * function. Intercept/override it if you want custom error handling. + * @param {Error} err the error object. + */ + req.onError = function (err) { + throw err; + }; + + /** + * Does the request to load a module for the browser case. + * Make this a separate function to allow other environments + * to override it. + * + * @param {Object} context the require context to find state. + * @param {String} moduleName the name of the module. + * @param {Object} url the URL to the module. + */ + req.load = function (context, moduleName, url) { + var config = (context && context.config) || {}, + node; + if (isBrowser) { + //In the browser so use a script tag + node = config.xhtml ? + document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : + document.createElement('script'); + node.type = config.scriptType || 'text/javascript'; + node.charset = 'utf-8'; + node.async = true; + + node.setAttribute('data-requirecontext', context.contextName); + node.setAttribute('data-requiremodule', moduleName); + + //Set up load listener. Test attachEvent first because IE9 has + //a subtle issue in its addEventListener and script onload firings + //that do not match the behavior of all other browsers with + //addEventListener support, which fire the onload event for a + //script right after the script execution. See: + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution + //UNFORTUNATELY Opera implements attachEvent but does not follow the script + //script execution mode. + if (node.attachEvent && + //Check if node.attachEvent is artificially added by custom script or + //natively supported by browser + //read https://github.com/jrburke/requirejs/issues/187 + //if we can NOT find [native code] then it must NOT natively supported. + //in IE8, node.attachEvent does not have toString() + //Note the test for "[native code" with no closing brace, see: + //https://github.com/jrburke/requirejs/issues/273 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && + !isOpera) { + //Probably IE. IE (at least 6-8) do not fire + //script onload right after executing the script, so + //we cannot tie the anonymous define call to a name. + //However, IE reports the script as being in 'interactive' + //readyState at the time of the define call. + useInteractive = true; + + node.attachEvent('onreadystatechange', context.onScriptLoad); + //It would be great to add an error handler here to catch + //404s in IE9+. However, onreadystatechange will fire before + //the error handler, so that does not help. If addEventListener + //is used, then IE will fire error before load, but we cannot + //use that pathway given the connect.microsoft.com issue + //mentioned above about not doing the 'script execute, + //then fire the script load event listener before execute + //next script' that other browsers do. + //Best hope: IE10 fixes the issues, + //and then destroys all installs of IE 6-9. + //node.attachEvent('onerror', context.onScriptError); + } else { + node.addEventListener('load', context.onScriptLoad, false); + node.addEventListener('error', context.onScriptError, false); + } + node.src = url; + + //For some cache cases in IE 6-8, the script executes before the end + //of the appendChild execution, so to tie an anonymous define + //call to the module name (which is stored on the node), hold on + //to a reference to this node, but clear after the DOM insertion. + currentlyAddingScript = node; + if (baseElement) { + head.insertBefore(node, baseElement); + } else { + head.appendChild(node); + } + currentlyAddingScript = null; + + return node; + } else if (isWebWorker) { + try { + //In a web worker, use importScripts. This is not a very + //efficient use of importScripts, importScripts will block until + //its script is downloaded and evaluated. However, if web workers + //are in play, the expectation that a build has been done so that + //only one script needs to be loaded anyway. This may need to be + //reevaluated if other use cases become common. + importScripts(url); + + //Account for anonymous modules + context.completeLoad(moduleName); + } catch (e) { + context.onError(makeError('importscripts', + 'importScripts failed for ' + + moduleName + ' at ' + url, + e, + [moduleName])); + } + } + }; + + function getInteractiveScript() { + if (interactiveScript && interactiveScript.readyState === 'interactive') { + return interactiveScript; + } + + eachReverse(scripts(), function (script) { + if (script.readyState === 'interactive') { + return (interactiveScript = script); + } + }); + return interactiveScript; + } + + //Look for a data-main script attribute, which could also adjust the baseUrl. + if (isBrowser) { + //Figure out baseUrl. Get it from the script tag with require.js in it. + eachReverse(scripts(), function (script) { + //Set the 'head' where we can append children by + //using the script's parent. + if (!head) { + head = script.parentNode; + } + + //Look for a data-main attribute to set main script for the page + //to load. If it is there, the path to data main becomes the + //baseUrl, if it is not already set. + dataMain = script.getAttribute('data-main'); + if (dataMain) { + //Set final baseUrl if there is not already an explicit one. + if (!cfg.baseUrl) { + //Pull off the directory of data-main for use as the + //baseUrl. + src = dataMain.split('/'); + mainScript = src.pop(); + subPath = src.length ? src.join('/') + '/' : './'; + + cfg.baseUrl = subPath; + dataMain = mainScript; + } + + //Strip off any trailing .js since dataMain is now + //like a module name. + dataMain = dataMain.replace(jsSuffixRegExp, ''); + + //Put the data-main script in the files to load. + cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain]; + + return true; + } + }); + } + + /** + * The function that handles definitions of modules. Differs from + * require() in that a string for the module should be the first argument, + * and the function to execute after dependencies are loaded should + * return a value to define the module corresponding to the first argument's + * name. + */ + define = function (name, deps, callback) { + var node, context; + + //Allow for anonymous modules + if (typeof name !== 'string') { + //Adjust args appropriately + callback = deps; + deps = name; + name = null; + } + + //This module may not have dependencies + if (!isArray(deps)) { + callback = deps; + deps = []; + } + + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!deps.length && isFunction(callback)) { + //Remove comments from the callback string, + //look for require calls, and pull them into the dependencies, + //but only if there are function args. + if (callback.length) { + callback + .toString() + .replace(commentRegExp, '') + .replace(cjsRequireRegExp, function (match, dep) { + deps.push(dep); + }); + + //May be a CommonJS thing even without require calls, but still + //could use exports, and module. Avoid doing exports and module + //work though if it just needs require. + //REQUIRES the function to expect the CommonJS variables in the + //order listed below. + deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); + } + } + + //If in IE 6-8 and hit an anonymous define() call, do the interactive + //work. + if (useInteractive) { + node = currentlyAddingScript || getInteractiveScript(); + if (node) { + if (!name) { + name = node.getAttribute('data-requiremodule'); + } + context = contexts[node.getAttribute('data-requirecontext')]; + } + } + + //Always save off evaluating the def call until the script onload handler. + //This allows multiple modules to be in a file without prematurely + //tracing dependencies, and allows for anonymous module support, + //where the module name is not known until the script onload event + //occurs. If no context, use the global queue, and get it processed + //in the onscript load callback. + (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); + }; + + define.amd = { + jQuery: true + }; + + + /** + * Executes the text. Normally just uses eval, but can be modified + * to use a better, environment-specific call. Only used for transpiling + * loader plugins, not for plain JS modules. + * @param {String} text the text to execute/evaluate. + */ + req.exec = function (text) { + /*jslint evil: true */ + return eval(text); + }; + + //Set up with config info. + req(cfg); +}(this)); diff --git a/demos/snap-ad/site/js/vendor/require.min.js b/demos/snap-ad/site/js/vendor/require.min.js new file mode 100644 index 0000000..84d1d67 --- /dev/null +++ b/demos/snap-ad/site/js/vendor/require.min.js @@ -0,0 +1,36 @@ +/* + RequireJS 2.1.10 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. + Available via the MIT or new BSD license. + see: http://github.com/jrburke/requirejs for details +*/ +var requirejs,require,define; +(function(ca){function G(b){return"[object Function]"===N.call(b)}function H(b){return"[object Array]"===N.call(b)}function v(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&& +(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a= +this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f); +if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval", +"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(K,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b, +a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(K,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m, +nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b, +a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild= +!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(K,f))return K[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}M();i.nextTick(function(){M();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!== +d&&(!("."===g||".."===g)||1g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)): +(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,M=g,D?y.insertBefore(g,D):y.appendChild(g),M=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(L=b.getAttribute("data-main"))return q=L,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl= +Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=L),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=M))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b|| +(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this); diff --git a/demos/snap-ad/src/.sass-cache/7eb2e4ecfecd432261de95f74b5302c6e0956ac9/screen.scssc b/demos/snap-ad/src/.sass-cache/7eb2e4ecfecd432261de95f74b5302c6e0956ac9/screen.scssc new file mode 100644 index 0000000000000000000000000000000000000000..7992a728d9d5c54de869426d8c09df6a90d24ed4 GIT binary patch literal 6370 zcmcIo&2!th6}Qz6Ba({kIPp3k8;2`zE!%4;vgD5#nAzn{CYjOfW}DXOq2q&xqM#TJ zKU9*6?PhZ9wf{sfz4X?2n-81S9A`+Y|gy_*EQO_TR5hpXzs!jPXGB_Plj|7fSdi6VQ z=#PNwQ#X#g8q!|8!P?0juuO+7X;K*1xD$`Di!i&W1&0Hq2tGMJe33pwGj zNvi--hT|Mp>9!q@`+oqb+aP2djw6@pQ#~e$2CUAU`0T?R+lueotLm#UF>|JU9fc!~ z9$sZfFEPlPL&vAyB|pZr-#gxzs9ncyL`Mli$4Nwkw^h8>tFJbGJtBd1>;!RR$BIcr zhZ6M55kZS|K!Su0DT#2+Ht-Ud;f_6mb5G;TAaO2GH6Z8A6+ld#lQ4~!nGUDY+upGG z5HHm5qOflqI3s0W#uMKO@p6?zjPD79;1vNm{-P?hTgdM+X${}+)j6K{K^s2|@gog? z$#H`fy9ok`FT)K#u3e20UJLOPj>O}}F*gLq!UAX~@xT`TN&g z?}r0!glp78Ulu*;g-3kATo>{xK4_7_H#i2U+v^proHJq(OViY z3ulUJZT|ae4etosN%%~69K~UjXHXl3G)Rb;y_(H(3e-{=sDxbbIKKuc{40rw+OWZJ zSec3gtk|c50>0Xbnc?uTc~1K8Xwpo=v3u5Z9nTBLLJH*%dJqO=1~Omdk-0Bfjvs&+T5*k8jTGVV>F2jdgs)7;zgH z1F#yuf6MW|CcQ|vQuN%b)~0$Dtl0B^fg{rai!YRx1yOKc(F+=+X}MQlNg~Lt!!Yuj zVMNp5gCq}u7_-oPqO&wyO~O&m*G&3EuIU~b3g48m1&dHr-jU1mFdDEbYuYg@!tFFI zJrVFWAm>3rQUdS;Hdz&sWh|`+FUJ830h5s%F${&@bJDcn$kOrCm{n90uR)z(v4gQs zA_r>k={TTC3=P4m4Fx0gX)rkpXjvez(BJWTb!``9dC6_J1sQvr1+q2yQxp_2#h@-) zcX8b#P82lziAZL%jf_@{NwznTRVB~Ir0Y{H4=eWkKS0uSpq=PhM!9KX{92ew)y9#N zob6aD#ZBr3&Qh$6(s^~ZjhmNy@5WReV8x#Q*9=DLWXTA~i{(`?0U*)=FR)Xc4S&P^ zYLUAk>lA;l{1ERjN1DS;Xdhbk{9l1(13v}#U=^w09*welh$$vU(LHJ#=q!AnR-{P` zp%chq2(g>?!C4pi+JO!^xdp;(D;%#Pi^+Hp8t9(QJ0Ulr?rFk$Cc|Ytp(x*m5(DWh zeA&ugs z$$L3&xLFc_i|#VucGP(x?ijd>_hk1~V7AWy0cyLlFkci+PGIK!2WQk|Y?O5-CW&&4%kGbe7g50{!ph zC$@vQoi=}qg>5GNVJc3rVpsmjaFU~(cmEF^hbWOhs+00=oplVDM>){hm4BB!Sx%c& zj<`7To?Z*#oq#6d1wz%wYP+>RBcZ)Y6WWg%);~zB@$av1NTQbhwVef8C~m>x~D*Qn!*#e&N_`x4MV>TU*%B zKN=s6?WaOcWCn0^a=i3n^BXRq(W_Vf{)_Zs(P~V-Og6A#WY33i;KY*{vdV8=7|t?U z>Sd|4Vak&b-^N~eV1sy4K~@_?7q278N*_cx8LLr1CZ7j#FAm6Jj|{L;u1;Kpv$fJY zK(5X+0E~h&dyM;3Il*v*H?lS8Ex9n;LYL^hv4PJr7 z9R~=m;+I_&HruI7z_zrfXM5OnhkapgqCMp^ye&jl+6iJt1bcPxD)9%OiQTF{f^I9f zU34^j`^3)FmbyBG_XwOyu>S~SCaI{^jN{D1uE26acc>s-`<(DfgiqWH(zAdvCQ>Ab bHGyTCDZqhS`yf4N0MtKAG@DdQ)5(7Ub7TXi literal 0 HcmV?d00001 diff --git a/demos/snap-ad/src/assets/computer.svg b/demos/snap-ad/src/assets/computer.svg new file mode 100644 index 0000000..05c5c57 --- /dev/null +++ b/demos/snap-ad/src/assets/computer.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/src/assets/fonts/OpenSans-Light.ttf b/demos/snap-ad/src/assets/fonts/OpenSans-Light.ttf new file mode 100755 index 0000000000000000000000000000000000000000..0d381897da20345fa63112f19042561f44ee3aa0 GIT binary patch literal 222412 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%0AG%b#%#Weyp=oz<}IGPqm z)8c4aT%)1Wt!Z(MiMFk2@iJ>#98HU(X>l|yj;6)Yv^bg;N7LeHS{zM_Yxd#ySkvN~ zeHg82+}v^bg;*NE&CYg!yli=%0AG%cHosL)|1w>IGPqm)8c4a98HU( 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

      ;uKu%NE38 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 Cmj74) literal 0 HcmV?d00001 diff --git a/demos/snap-ad/src/assets/heart.svg b/demos/snap-ad/src/assets/heart.svg new file mode 100644 index 0000000..87fd258 --- /dev/null +++ b/demos/snap-ad/src/assets/heart.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/demos/snap-ad/src/assets/phone.svg b/demos/snap-ad/src/assets/phone.svg new file mode 100644 index 0000000..dbd26ca --- /dev/null +++ b/demos/snap-ad/src/assets/phone.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/src/assets/tablet.svg b/demos/snap-ad/src/assets/tablet.svg new file mode 100644 index 0000000..1783bb0 --- /dev/null +++ b/demos/snap-ad/src/assets/tablet.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/src/backup.jpg b/demos/snap-ad/src/backup.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e05cec7eb174f9af8b27c705ff395cd20ea288c GIT binary patch literal 34998 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

      X->BjGE64$W9Kqxg?62Tyj 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 + + + + + + + + Snap! SVG + + + + + + + + + + + + + + + + + + diff --git a/demos/snap-ad/src/js/app/app.js b/demos/snap-ad/src/js/app/app.js new file mode 100644 index 0000000..051c939 --- /dev/null +++ b/demos/snap-ad/src/js/app/app.js @@ -0,0 +1,269 @@ +define(function (require) { + + require('snap'); + + var App, + Heart = require('app/heart'), + Device = require('app/device'), + Burst = require('app/burst'); + Mesh = require('app/mesh'); + Logo = require('app/logo'); + + App = function () { + var instance = this; + + this.started = false; + + this.init = function () { + var timeline, + ad, + s, + cover, + device, + heart, + burst, + screen1, + text1, + text2, + text3, + text4, + resolveScreen, + logo, + meshA, + meshAContainer, + replaycount = 0, + WIDTH = 400, + HEIGHT = 400, + WHITE = "#ffffff", + GREEN = "#09ae8a"; + + this.started = true; + + ad = document.getElementById('ad'); + s = new Snap("#ad"); + cover = s.select('#cover'); + meshAContainer = s.select('#meshAContainer'); + screen1 = s.select('#screen1'); + text1 = s.select('#text1'); + text2 = s.select('#text2'); + text3 = s.select('#text3'); + text4 = s.select('#text4'); + replayBtn = s.select('#replay-btn'); + resolveScreen = s.select('#resolve'); + logo = new Logo(s); + + handle_RESIZE(); + window.addEventListener('resize', handle_RESIZE); + ad.addEventListener('click', handle_CLICK); + replayBtn.click(replay_CLICK); + + addMeshA(); + cover.remove(); + addHeart(); + addComputer(); + addBurst(); + + function addHeart() { + heart = new Heart(s, WIDTH / 2, HEIGHT / 2); + } + + function addComputer() { + device = new Device(s, WIDTH / 2, HEIGHT / 2); + device.setScreen(192, 112); + device.setBack(208, 148); + device.setScale(0.1); + text2.after(device.el); + } + + function addBurst() { + burst = new Burst(s); + } + + function addMeshA() { + meshA = new Mesh(s, meshAContainer, '#afafaf', '#afafaf'); + } + + function addMeshB() { + meshA.el.remove(); + meshB = new Mesh(s, meshBContainer, '#09ae8a', '#777777'); + } + + function showMeshB() { + if (mobilecheck() !== true) { + meshB.start(); + } + } + + function showComputer() { + text1.animate({y: 80}, 100); + text2.animate({y: 350}, 100); + device.animScale(10, 300, mina.bounce); + heart.animFill(WHITE); + } + + function toTablet() { + device.animRotation(-90); + device.animScreen(76, 100); + device.animBack(92, 132); + heart.animScale(0.5, 200); + } + + function toPhone() { + device.hideKeyboard(); + device.animScreen(48, 76); + device.animBack(56, 100); + heart.animScale(0.3); + } + + function rotate() { + device.animRotation(90); + heart.animScale(0.4); + } + + function zoom() { + meshA.stop(); + device.animScale(10, 600); + heart.animScale(4, 600); + burst.anim(); + } + + function greenMesh() { + + meshA.setColor('#09ae8a', '#777777'); + + if (mobilecheck() !== true) { + meshA.start(); + } + + device.animOpacity(0, 200); + screen1.animate({ + opacity: 0 + }, 100); + } + + function maskReveal() { + heart.mask(); + } + + function showText3() { + device.setScale(0.01); + text3.animate({ + opacity: 1 + }, 200); + } + + function hideText3() { + text3.animate({ + opacity: 0 + }, 200); + + if (mobilecheck() !== true) { + meshA.rippleColor('#afafaf', '#afafaf'); + } else { + meshA.setColor('#afafaf', '#afafaf'); + } + } + + function resolve() { + resolveScreen.animate({ + opacity: 1 + }, 200); + } + + function stop() { + logo.animate(); + meshA.stop(); + } + + function reset() { + resolveScreen.attr({ + opacity: 0 + }); + + screen1.attr({ + opacity: 1 + }); + + text1.attr({y: 130}); + text2.attr({y: 300}); + + heart.setScale(1); + heart.setFill('#0DAE8A'); + heart.unmask(); + device.setOpacity(1); + device.setScreen(192, 112); + device.setBack(208, 148); + device.showKeyboard(); + meshA.start(); + burst.reset(); + } + + function replay_CLICK(e) { + e.stopPropagation(); + + replaycount += 1; + ga('send', 'event', 'button', 'click', 'replay', replaycount); + reset(); + run(); + } + + function handle_CLICK(e) { + ga('send', 'event', 'button', 'click', 'ad'); + top.window.location.href = 'http://snapsvg.io/'; + } + + function handle_RESIZE() { + var _w = window.innerWidth, + scale = _w / 400; + + ad.style.webkitTransform = 'scale(' + scale + ')'; + ad.style.MozTransform = 'scale(' + scale + ')'; + ad.style.msTransform = 'scale(' + scale + ')'; + ad.style.oTransform = 'scale(' + scale + ')'; + ad.style.transform = 'scale(' + scale + ')'; + + } + + function run() { + if (mobilecheck() !== true) { + meshA.start(); + } + setTimeout(showComputer, 2000); + setTimeout(toPhone, 3000); + setTimeout(rotate, 4000); + setTimeout(toTablet, 5000); + setTimeout(zoom, 6000); + setTimeout(greenMesh, 6300); + setTimeout(maskReveal, 6700); + setTimeout(showText3, 7000); + setTimeout(hideText3, 10000); + setTimeout(resolve, 10500); + setTimeout(stop, 10900); + } + + function basic() { + screen1.attr({opacity: 0}); + heart.el.attr({opacity: 0}); + replayBtn.attr({opacity: 0}); + logo.show(); + text4.select('tspan').attr({opacity: 0}); + text4.select('tspan:nth-child(2)').attr({y: 120}); + resolveScreen.attr({opacity: 1}); + } + + if (window.replay !== true) { + replayBtn.attr({opacity: 0}); + } + + if (window.supported !== false) { + run(); + } else { + basic(); + } + + } + + } + + return App; +}); \ No newline at end of file diff --git a/demos/snap-ad/src/js/app/burst.js b/demos/snap-ad/src/js/app/burst.js new file mode 100644 index 0000000..ae912cf --- /dev/null +++ b/demos/snap-ad/src/js/app/burst.js @@ -0,0 +1,52 @@ +define(function (require) { + + var Burst = function (s, x, y) { + var instance = this, + polygons, + mask, + maskCircle, + maskBg; + + this.el = s.select("#burst"); + + mask = s.g(); + mask.toDefs(); + + maskBg = s.rect(-200, -200, 400, 400); + maskBg.attr({ + fill: 'white' + }); + mask.append(maskBg); + + maskCircle = s.circle(0, 0, 30); + mask.append(maskCircle); + + this.el.attr({ + mask: mask + }); + + this.anim = function () { + this.el.animate({ + opacity: 1 + }, 100); + + maskCircle.animate({ + transform: 'scale(6)' + }, 300); + + setTimeout(function () { + instance.el.animate({ + opacity: 0 + }, 100); + }, 300) + } + + this.reset = function () { + maskCircle.attr({ + transform: 'scale(1)' + }); + } + } + + return Burst; +}); \ No newline at end of file diff --git a/demos/snap-ad/src/js/app/device.js b/demos/snap-ad/src/js/app/device.js new file mode 100644 index 0000000..3d33883 --- /dev/null +++ b/demos/snap-ad/src/js/app/device.js @@ -0,0 +1,218 @@ +define(function (require) { + + var Device = function (s, x, y) { + var instance = this; + + this.el = s.g(); + this.matrix = new Snap.Matrix(); + this.matrix.translate(x, y); + this.el.transform(this.matrix.toTransformString()); + + this.keyboardMatrix = new Snap.Matrix(); + this.keyboardMatrix.translate(0, 70); + + instance.maskElement = s.polygon(); + instance.maskElement.toDefs(); + + addBack(); + addScreen(); + //addGloss(); + addKeyboard(); + + function addBack() { + instance.back = s.rect(0, 0, 0, 0); + instance.back.attr({ + fill: '#696969' + }); + + instance.el.append(instance.back); + } + + function addScreen() { + instance.scr = s.rect(0, 0, 0, 0); + instance.scr.attr({ + fill: "#09ae8a" + }); + + instance.el.append(instance.scr); + } + + function addKeyboard() { + var p1, + p2; + + instance.keyboard = s.g(); + instance.keyboard.transform(instance.keyboardMatrix.toTransformString()); + + p1 = s.polygon('-103.324,0 -135.324,32 136.676,32 104.676,0 '); + p1.attr({ + fill: '#818181' + }); + + p2 = s.polygon('127.774,40 -128.226,40 -136.226,32 135.774,32 '); + p2.attr({ + fill: '#676767' + }); + + instance.keyboard.append(p1); + instance.keyboard.append(p2); + instance.el.append(instance.keyboard); + } + + function addGloss() { + instance.gl = s.rect(0, 0, 0, 0); + instance.gl.attr({ + opacity: 0.2, + fill: "white", + clipPath: instance.maskElement + }); + + instance.el.append(instance.gl); + } + + this.hideKeyboard = function () { + this.keyboardMatrix = new Snap.Matrix(); + instance.keyboardMatrix.translate(0, 50); + instance.keyboardMatrix.scale(0.01, 0.01, 0, 0); + instance.keyboard.animate({ + opacity: 0, + transform: instance.keyboardMatrix.toTransformString() + }, 100); + } + + this.showKeyboard = function () { + this.keyboardMatrix = new Snap.Matrix(); + instance.keyboardMatrix.translate(0, 70); + instance.keyboardMatrix.scale(1, 1, 0, 0); + instance.keyboard.attr({ + opacity: 1, + transform: instance.keyboardMatrix.toTransformString() + }); + } + + this.setScreen = function(w, h) { + this.scr.attr({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }); + } + + this.setBack = function (w, h) { + this.back.attr({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }); + + /* + this.gl.attr({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }); + + var pointString = -w / 2 + ' ' + -h / 2 + ',' + w / 2 + ' ' + -h / 2 + ',' + -w / 2 + ' ' + h / 2; + + instance.maskElement.attr({ + points: pointString + }); + */ + } + + this.setScale = function (scale) { + this.matrix.scale(scale, scale, 0, 0); + this.el.transform(this.matrix.toTransformString()); + } + + this.animScreen = function(w, h) { + this.scr.animate({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }, 100); + } + + this.animBack = function (w, h) { + this.back.animate({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }, 100); + + /* + this.gl.animate({ + x: -w / 2, + y: -h / 2, + width: w, + height: h + }, 100); + + var pointString = -w / 2 + ' ' + -h / 2 + ',' + w / 2 + ' ' + -h / 2 + ',' + -w / 2 + ' ' + h / 2; + + instance.maskElement.attr({ + points: pointString + }); + */ + } + + this.animRotation = function (r) { + instance.matrix.rotate(r, 0, 0); + + instance.el.animate({ + transform: instance.matrix.toTransformString() + }, 100, mina.easeIn); + + /* + if (r == 90) { + var w = 100, + h = 56, + pointString = -w / 2 + ' ' + -h / 2 + ',' + w / 2 + ' ' + -h / 2 + ',' + -w / 2 + ' ' + h / 2; + + instance.maskElement.attr({ + points: pointString + }); + + instance.maskElement.animate({ + transform: 'rotate(-90)' + }, 100, mina.easeIn); + } else { + instance.maskElement.animate({ + transform: 'rotate(0)' + }, 100, mina.easeIn); + } + */ + } + + this.animScale = function (scale, dur, ease) { + dur = dur ? dur : 100; + ease = ease ? ease : mina.easeout; + + this.matrix.scale(scale, scale, 0, 0); + this.el.animate({ + transform: this.matrix.toTransformString() + }, dur, ease); + } + + this.animOpacity = function (opacity, dur) { + dur = dur ? dur : 200; + + this.el.animate({ + opacity: opacity + }, dur); + } + + this.setOpacity = function (opacity) { + this.el.attr({ + opacity: opacity + }); + } + } + + return Device; +}); \ No newline at end of file diff --git a/demos/snap-ad/src/js/app/heart.js b/demos/snap-ad/src/js/app/heart.js new file mode 100644 index 0000000..a5f9f1e --- /dev/null +++ b/demos/snap-ad/src/js/app/heart.js @@ -0,0 +1,103 @@ +define(function (require) { + + var Heart = function (s, x, y) { + var instance = this, + heart, + heartMatrix, + totalMaskVertices = 50; + + this.el = s.select("#heart"); + heart = this.el.select('#heart-shape'); + + instance.maskElement = s.path(getPath(totalMaskVertices)); + instance.el.attr({ + clipPath: instance.maskElement + }); + + this.animFill = function (f, dur) { + heart.animate({ + fill: f + }, 200); + } + + this.setFill = function (f, dur) { + heart.attr({ + fill: f + }, 200); + } + + this.animScale = function (scale, dur) { + dur = dur ? dur : 300; + + this.matrix = new Snap.Matrix(); + this.matrix.translate(x, y); + this.matrix.scale(scale); + this.el.animate({ + transform: this.matrix.toTransformString() + }, dur, mina.bounce); + } + + this.setScale = function (scale, dur) { + dur = dur ? dur : 300; + + this.matrix = new Snap.Matrix(); + this.matrix.translate(x, y); + this.matrix.scale(scale, scale, 0, 0); + this.el.attr({ + transform: this.matrix.toTransformString() + }); + + } + + this.mask = function () { + var n = totalMaskVertices; + + instance.maskElement.attr({ + d: getPath(n) + }); + + function updatePath() { + n -= 1; + instance.maskElement.attr({ + d: getPath(n) + }); + + if (n > 0) { + setTimeout(updatePath, 10); + } + } + + setTimeout(updatePath, 10); + } + + this.unmask = function () { + instance.maskElement.attr({ + d: getPath(totalMaskVertices) + }); + } + + function getPath(n) { + var pathString, + i, + _x, + _y; + + pathString = "M0 0"; + + for (i = 0; i < n + 1; i += 1) { + a = 2 * Math.PI * i / totalMaskVertices; + a += Math.PI; + + _x = Math.sin(a) * 50; + _y = Math.cos(a) * 50; + + pathString += "L" + _x + " " + _y; + } + + pathString += "Z"; + return pathString; + } + } + + return Heart; +}); \ No newline at end of file diff --git a/demos/snap-ad/src/js/app/logo.js b/demos/snap-ad/src/js/app/logo.js new file mode 100644 index 0000000..b592e83 --- /dev/null +++ b/demos/snap-ad/src/js/app/logo.js @@ -0,0 +1,59 @@ +define(function (require) { + + var Logo = function (s) { + var instance = this, + logo, + parts = [ + ['top', 0, 20], + ['left', 20, 0], + ['bottom', 0, -20], + ['right', -20, 0] + ], + components = [], + i = 0, + k = 0, + isLogoAnimated = false, + isCrocAnimated = false, + isCroc2Animated = false; + + logo = s.select("#snap-logo"); + + for (i = 0; i < parts.length; i++) { + var el = parts[i] + elid = el[0]; + element = logo.select("#snap-logo-" + elid); + element.attr({opacity:0, transform: "t" + (el[1]) + "," + (el[2])}); + components.push(element); + } + + function animateEach() { + if (!components[k]) { + return; + } + components[k].animate({ + transform: "t" + (0) + "," + (0), + opacity: 1 + }, 250, mina.easeout); + setTimeout(animateEach, 150); + k++; + }; + + this.animate = function () { + setTimeout(animateEach, 150); + } + + this.show = function () { + var i; + + for (i = 0; i < components.length; i += 1) { + components[i].attr({ + transform: "t" + (0) + "," + (0), + opacity: 1 + }); + } + + } + } + + return Logo; +}); \ No newline at end of file diff --git a/demos/snap-ad/src/js/app/mesh.js b/demos/snap-ad/src/js/app/mesh.js new file mode 100644 index 0000000..f8b90af --- /dev/null +++ b/demos/snap-ad/src/js/app/mesh.js @@ -0,0 +1,143 @@ +define(function (require) { + + require('vendor/fss'); + + var Mesh = function (s, container, colorA, colorB) { + var instance = this, + _width = 440, + _height = 440, + now, + start = Date.now(), + renderer, + scene, + geometry, + material, + mesh, + light; + + instance.animating = false; + + instance.init = function () { + renderer = new FSS.SVGRenderer(s); + renderer.setSize(_width, _height); + renderer.element.transform('translate(-20, -20)'); //keep edges from showing + + instance.el = renderer.element; + + container.append(renderer.element); + + scene = new FSS.Scene(); + material = new FSS.Material(colorA, colorB); + geometry = new FSS.Plane(_width, _height, 10, 10, s, material); + mesh = new FSS.Mesh(geometry, material); + scene.add(mesh); + + light = new FSS.Light('#eeeeee', '#eeeeee'); + light.setPosition(300*Math.sin(0.001), 200*Math.cos(0.0005), 100); + scene.add(light); + + now = Date.now() - start; + + tweakMesh(); + distortMesh(); + renderer.render(scene); + } + + instance.start = function () { + instance.animating = true; + animate(); + } + + instance.stop = function () { + instance.animating = false; + } + + instance.setColor = function (colorA, colorB) { + var i; + + material = new FSS.Material(colorA, colorB); + + for (i = geometry.triangles.length - 1; i > -1; i -= 1) { + geometry.triangles[i].material = material; + } + + animate(); + } + + instance.rippleColor = function (colorA, colorB) { + var i; + + material = new FSS.Material(colorA, colorB); + + function colorTriangle(j) { + geometry.triangles[j].material = material; + + if (j == 0) { + setTimeout(function () { + animate(); + }, 10); //force clear + } + } + + for (i = geometry.triangles.length - 1; i > -1; i -= 1) { + var speed = 200 + Math.sin(0.1 + Math.abs(geometry.triangles[i].centroid[0] / geometry.triangles[i].centroid[1])) * 100; + setTimeout(colorTriangle, speed * 2, i); + } + } + + + function tweakMesh() { + var v, vertex; + + for (v = geometry.vertices.length - 1; v >= 0; v--) { + vertex = geometry.vertices[v]; + vertex.anchor = FSS.Vector3.clone(vertex.position); + vertex.step = FSS.Vector3.create( + Math.randomInRange(0.2, 1.0), + Math.randomInRange(0.2, 1.0), + Math.randomInRange(0.2, 1.0) + ); + vertex.time = Math.randomInRange(0, Math.PIM2); + } + } + + function distortMesh() { + var v, + vertex, + ox, oy, oz, + offset = 10 / 2; + + for (v = geometry.vertices.length - 1; v >= 0; v--) { + vertex = geometry.vertices[v]; + ox = Math.sin(vertex.time + vertex.step[0] * now * 0.002); + oy = Math.cos(vertex.time + vertex.step[1] * now * 0.002); + oz = Math.sin(vertex.time + vertex.step[2] * now * 0.002); + FSS.Vector3.set(vertex.position, + 0.2 * geometry.segmentWidth * ox, + 0.1 * geometry.sliceHeight * oy, + 0.7 * offset * oz - offset); + FSS.Vector3.add(vertex.position, vertex.anchor); + } + + geometry.dirty = true; + } + + function animate() { + now = Date.now() - start; + + if (mobilecheck() !== true) { + distortMesh(); + } + + renderer.render(scene); + + if (instance.animating !== false) { + requestAnimationFrame(animate); + } + } + + instance.init(); + } + + return Mesh; +}); \ No newline at end of file diff --git a/demos/snap-ad/src/js/main.js b/demos/snap-ad/src/js/main.js new file mode 100644 index 0000000..434a475 --- /dev/null +++ b/demos/snap-ad/src/js/main.js @@ -0,0 +1,94 @@ +/*global require*/ + +require.config({ + shim: { + + }, + paths: { + snap: 'vendor/snap.svg', + tweenlite: 'vendor/greensock/TweenLite', + timelinelite: 'vendor/greensock/TimelineLite' + } +}); + +/** +* check support +*/ +window.ua = navigator.userAgent.toLowerCase(); +window.isAndroid = ua.indexOf("android") > -1; +window.isSafari = ua.indexOf("safari") > -1 && ua.indexOf("chrome") === -1; + +function checkSVG() { + return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect; +} + +/** +* check mobile +*/ +window.mobilecheck = function() { + var check = false; + (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); + return check; +} + +function addFallback() { + var link, + img; + + link = document.createElement('a'); + link.href = "http://snapsvg.io/"; + document.body.appendChild(link); + + img = new Image(); + img.src = "backup.jpg"; + img.style.position = "absolute"; + img.style.top = "0"; + img.style.left = "0"; + img.width = "100%"; + link.appendChild(img); +} + +window.supported = true; +window.replay = true; + +require(['app/app'], function (App) { + + if (checkSVG() !== true) { + addFallback(); + return; + } + + if (isAndroid === true) { + window.supported = false; + } + + if (isSafari === true) { + window.replay = false; + } + + window.app = new App(); + //app.init(); //fired from font loading +}); + + + +/** +* font loading +*/ +WebFontConfig = { + google: { + families: ['Open+Sans:300:latin', 'Source+Sans+Pro::latin'] + }, + inactive: function () { + if (typeof(app) !== 'undefined' && app.started !== true) { + app.init(); + } + }, + fontactive: function(familyName, fvd) { + if (typeof(app) !== 'undefined' && familyName == 'Open Sans') { + if (app.started !== true) { + app.init(); + } + } + } +} \ No newline at end of file diff --git a/demos/snap-ad/src/js/vendor/fss.js b/demos/snap-ad/src/js/vendor/fss.js new file mode 100755 index 0000000..cfe5bf6 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss.js @@ -0,0 +1,760 @@ +//============================================================ +// +// Copyright (C) 2013 Matthew Wagerfield +// +// Twitter: https://twitter.com/mwagerfield +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, +// sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY +// OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +// +//============================================================ + +/** + * Defines the Flat Surface Shader namespace for all the awesomeness to exist upon. + * @author Matthew Wagerfield + */ +FSS = { + FRONT : 0, + BACK : 1, + DOUBLE : 2, + SVGNS : 'http://www.w3.org/2000/svg' +}; + +/** + * @class Array + * @author Matthew Wagerfield + */ +FSS.Array = typeof Float32Array === 'function' ? Float32Array : Array; + +/** + * @class Utils + * @author Matthew Wagerfield + */ +FSS.Utils = { + isNumber: function(value) { + return !isNaN(parseFloat(value)) && isFinite(value); + } +}; + +/** + * Request Animation Frame Polyfill. + * @author Paul Irish + * @see https://gist.github.com/paulirish/1579671 + */ +(function() { + + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function(callback, element) { + var currentTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currentTime - lastTime)); + var id = window.setTimeout(function() { + callback(currentTime + timeToCall); + }, timeToCall); + lastTime = currentTime + timeToCall; + return id; + }; + } + + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; + } + +}()); + +/** + * @object Math Augmentation + * @author Matthew Wagerfield + */ +Math.PIM2 = Math.PI*2; +Math.PID2 = Math.PI/2; +Math.randomInRange = function(min, max) { + return min + (max - min) * Math.random(); +}; +Math.clamp = function(value, min, max) { + value = Math.max(value, min); + value = Math.min(value, max); + return value; +}; + +/** + * @object Vector3 + * @author Matthew Wagerfield + */ +FSS.Vector3 = { + create: function(x, y, z) { + var vector = new FSS.Array(3); + this.set(vector, x, y, z); + return vector; + }, + clone: function(a) { + var vector = this.create(); + this.copy(vector, a); + return vector; + }, + set: function(target, x, y, z) { + target[0] = x || 0; + target[1] = y || 0; + target[2] = z || 0; + return this; + }, + setX: function(target, x) { + target[0] = x || 0; + return this; + }, + setY: function(target, y) { + target[1] = y || 0; + return this; + }, + setZ: function(target, z) { + target[2] = z || 0; + return this; + }, + copy: function(target, a) { + target[0] = a[0]; + target[1] = a[1]; + target[2] = a[2]; + return this; + }, + add: function(target, a) { + target[0] += a[0]; + target[1] += a[1]; + target[2] += a[2]; + return this; + }, + addVectors: function(target, a, b) { + target[0] = a[0] + b[0]; + target[1] = a[1] + b[1]; + target[2] = a[2] + b[2]; + return this; + }, + addScalar: function(target, s) { + target[0] += s; + target[1] += s; + target[2] += s; + return this; + }, + subtract: function(target, a) { + target[0] -= a[0]; + target[1] -= a[1]; + target[2] -= a[2]; + return this; + }, + subtractVectors: function(target, a, b) { + target[0] = a[0] - b[0]; + target[1] = a[1] - b[1]; + target[2] = a[2] - b[2]; + return this; + }, + subtractScalar: function(target, s) { + target[0] -= s; + target[1] -= s; + target[2] -= s; + return this; + }, + multiply: function(target, a) { + target[0] *= a[0]; + target[1] *= a[1]; + target[2] *= a[2]; + return this; + }, + multiplyVectors: function(target, a, b) { + target[0] = a[0] * b[0]; + target[1] = a[1] * b[1]; + target[2] = a[2] * b[2]; + return this; + }, + multiplyScalar: function(target, s) { + target[0] *= s; + target[1] *= s; + target[2] *= s; + return this; + }, + divide: function(target, a) { + target[0] /= a[0]; + target[1] /= a[1]; + target[2] /= a[2]; + return this; + }, + divideVectors: function(target, a, b) { + target[0] = a[0] / b[0]; + target[1] = a[1] / b[1]; + target[2] = a[2] / b[2]; + return this; + }, + divideScalar: function(target, s) { + if (s !== 0) { + target[0] /= s; + target[1] /= s; + target[2] /= s; + } else { + target[0] = 0; + target[1] = 0; + target[2] = 0; + } + return this; + }, + cross: function(target, a) { + var x = target[0]; + var y = target[1]; + var z = target[2]; + target[0] = y*a[2] - z*a[1]; + target[1] = z*a[0] - x*a[2]; + target[2] = x*a[1] - y*a[0]; + return this; + }, + crossVectors: function(target, a, b) { + target[0] = a[1]*b[2] - a[2]*b[1]; + target[1] = a[2]*b[0] - a[0]*b[2]; + target[2] = a[0]*b[1] - a[1]*b[0]; + return this; + }, + min: function(target, value) { + if (target[0] < value) { target[0] = value; } + if (target[1] < value) { target[1] = value; } + if (target[2] < value) { target[2] = value; } + return this; + }, + max: function(target, value) { + if (target[0] > value) { target[0] = value; } + if (target[1] > value) { target[1] = value; } + if (target[2] > value) { target[2] = value; } + return this; + }, + clamp: function(target, min, max) { + this.min(target, min); + this.max(target, max); + return this; + }, + limit: function(target, min, max) { + var length = this.length(target); + if (min !== null && length < min) { + this.setLength(target, min); + } else if (max !== null && length > max) { + this.setLength(target, max); + } + return this; + }, + dot: function(a, b) { + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; + }, + normalise: function(target) { + return this.divideScalar(target, this.length(target)); + }, + negate: function(target) { + return this.multiplyScalar(target, -1); + }, + distanceSquared: function(a, b) { + var dx = a[0] - b[0]; + var dy = a[1] - b[1]; + var dz = a[2] - b[2]; + return dx*dx + dy*dy + dz*dz; + }, + distance: function(a, b) { + return Math.sqrt(this.distanceSquared(a, b)); + }, + lengthSquared: function(a) { + return a[0]*a[0] + a[1]*a[1] + a[2]*a[2]; + }, + length: function(a) { + return Math.sqrt(this.lengthSquared(a)); + }, + setLength: function(target, l) { + var length = this.length(target); + if (length !== 0 && l !== length) { + this.multiplyScalar(target, l / length); + } + return this; + } +}; + +/** + * @object Vector4 + * @author Matthew Wagerfield + */ +FSS.Vector4 = { + create: function(x, y, z, w) { + var vector = new FSS.Array(4); + this.set(vector, x, y, z); + return vector; + }, + set: function(target, x, y, z, w) { + target[0] = x || 0; + target[1] = y || 0; + target[2] = z || 0; + target[3] = w || 0; + return this; + }, + setX: function(target, x) { + target[0] = x || 0; + return this; + }, + setY: function(target, y) { + target[1] = y || 0; + return this; + }, + setZ: function(target, z) { + target[2] = z || 0; + return this; + }, + setW: function(target, w) { + target[3] = w || 0; + return this; + }, + add: function(target, a) { + target[0] += a[0]; + target[1] += a[1]; + target[2] += a[2]; + target[3] += a[3]; + return this; + }, + multiplyVectors: function(target, a, b) { + target[0] = a[0] * b[0]; + target[1] = a[1] * b[1]; + target[2] = a[2] * b[2]; + target[3] = a[3] * b[3]; + return this; + }, + multiplyScalar: function(target, s) { + target[0] *= s; + target[1] *= s; + target[2] *= s; + target[3] *= s; + return this; + }, + min: function(target, value) { + if (target[0] < value) { target[0] = value; } + if (target[1] < value) { target[1] = value; } + if (target[2] < value) { target[2] = value; } + if (target[3] < value) { target[3] = value; } + return this; + }, + max: function(target, value) { + if (target[0] > value) { target[0] = value; } + if (target[1] > value) { target[1] = value; } + if (target[2] > value) { target[2] = value; } + if (target[3] > value) { target[3] = value; } + return this; + }, + clamp: function(target, min, max) { + this.min(target, min); + this.max(target, max); + return this; + } +}; + +/** + * @class Color + * @author Matthew Wagerfield + */ +FSS.Color = function(hex, opacity) { + this.rgba = FSS.Vector4.create(); + this.hex = hex || '#000000'; + this.opacity = FSS.Utils.isNumber(opacity) ? opacity : 1; + this.set(this.hex, this.opacity); +}; + +FSS.Color.prototype = { + set: function(hex, opacity) { + hex = hex.replace('#', ''); + var size = hex.length / 3; + this.rgba[0] = parseInt(hex.substring(size*0, size*1), 16) / 255; + this.rgba[1] = parseInt(hex.substring(size*1, size*2), 16) / 255; + this.rgba[2] = parseInt(hex.substring(size*2, size*3), 16) / 255; + this.rgba[3] = FSS.Utils.isNumber(opacity) ? opacity : this.rgba[3]; + return this; + }, + hexify: function(channel) { + var hex = Math.ceil(channel*255).toString(16); + if (hex.length === 1) { hex = '0' + hex; } + return hex; + }, + format: function() { + var r = this.hexify(this.rgba[0]); + var g = this.hexify(this.rgba[1]); + var b = this.hexify(this.rgba[2]); + this.hex = '#' + r + g + b; + return this.hex; + } +}; + +/** + * @class Object + * @author Matthew Wagerfield + */ +FSS.Object = function() { + this.position = FSS.Vector3.create(); +}; + +FSS.Object.prototype = { + setPosition: function(x, y, z) { + FSS.Vector3.set(this.position, x, y, z); + return this; + } +}; + +/** + * @class Light + * @author Matthew Wagerfield + */ +FSS.Light = function(ambient, diffuse) { + FSS.Object.call(this); + this.ambient = new FSS.Color(ambient || '#FFFFFF'); + this.diffuse = new FSS.Color(diffuse || '#FFFFFF'); + this.ray = FSS.Vector3.create(); +}; + +FSS.Light.prototype = Object.create(FSS.Object.prototype); + +/** + * @class Vertex + * @author Matthew Wagerfield + */ +FSS.Vertex = function(x, y, z) { + this.position = FSS.Vector3.create(x, y, z); +}; + +FSS.Vertex.prototype = { + setPosition: function(x, y, z) { + FSS.Vector3.set(this.position, x, y, z); + return this; + } +}; + +/** + * @class Triangle + * @author Matthew Wagerfield + */ +FSS.Triangle = function(a, b, c, s, material) { + this.a = a || new FSS.Vertex(); + this.b = b || new FSS.Vertex(); + this.c = c || new FSS.Vertex(); + this.vertices = [this.a, this.b, this.c]; + this.u = FSS.Vector3.create(); + this.v = FSS.Vector3.create(); + this.centroid = FSS.Vector3.create(); + this.normal = FSS.Vector3.create(); + this.material = material || new FSS.Material(); + this.color = new FSS.Color(); + this.polygon = s.polygon(); + this.polygon.attr({ + 'stroke-linejoin': 'round', + 'stroke-miterlimit': 1, + 'stroke-width': 1 + }); + + this.computeCentroid(); + this.computeNormal(); +}; + +FSS.Triangle.prototype = { + computeCentroid: function() { + this.centroid[0] = this.a.position[0] + this.b.position[0] + this.c.position[0]; + this.centroid[1] = this.a.position[1] + this.b.position[1] + this.c.position[1]; + this.centroid[2] = this.a.position[2] + this.b.position[2] + this.c.position[2]; + FSS.Vector3.divideScalar(this.centroid, 3); + return this; + }, + computeNormal: function() { + FSS.Vector3.subtractVectors(this.u, this.b.position, this.a.position); + FSS.Vector3.subtractVectors(this.v, this.c.position, this.a.position); + FSS.Vector3.crossVectors(this.normal, this.u, this.v); + FSS.Vector3.normalise(this.normal); + return this; + } +}; + +/** + * @class Geometry + * @author Matthew Wagerfield + */ +FSS.Geometry = function() { + this.vertices = []; + this.triangles = []; + this.dirty = false; +}; + +FSS.Geometry.prototype = { + update: function() { + if (this.dirty) { + var t,triangle; + for (t = this.triangles.length - 1; t >= 0; t--) { + triangle = this.triangles[t]; + triangle.computeCentroid(); + triangle.computeNormal(); + } + this.dirty = false; + } + return this; + } +}; + +/** + * @class Plane + * @author Matthew Wagerfield + */ +FSS.Plane = function(width, height, segments, slices, s, material) { + FSS.Geometry.call(this); + this.width = width || 100; + this.height = height || 100; + this.segments = segments || 4; + this.slices = slices || 4; + this.segmentWidth = this.width / this.segments; + this.sliceHeight = this.height / this.slices; + + // Cache Variables + var x, y, v0, v1, v2, v3, + vertex, triangle, vertices = [], + offsetX = this.width * -0.5, + offsetY = this.height * 0.5; + + // Add Vertices + for (x = 0; x <= this.segments; x++) { + vertices.push([]); + for (y = 0; y <= this.slices; y++) { + vertex = new FSS.Vertex(offsetX + x*this.segmentWidth, offsetY - y*this.sliceHeight); + vertices[x].push(vertex); + this.vertices.push(vertex); + } + } + + // Add Triangles + for (x = 0; x < this.segments; x++) { + for (y = 0; y < this.slices; y++) { + v0 = vertices[x+0][y+0]; + v1 = vertices[x+0][y+1]; + v2 = vertices[x+1][y+0]; + v3 = vertices[x+1][y+1]; + t0 = new FSS.Triangle(v0, v1, v2, s, material); + t1 = new FSS.Triangle(v2, v1, v3, s, material); + this.triangles.push(t0, t1); + } + } +}; + +FSS.Plane.prototype = Object.create(FSS.Geometry.prototype); + +/** + * @class Material + * @author Matthew Wagerfield + */ +FSS.Material = function(ambient, diffuse) { + this.ambient = new FSS.Color(ambient || '#444444'); + this.diffuse = new FSS.Color(diffuse || '#FFFFFF'); + this.slave = new FSS.Color(); +}; + +/** + * @class Mesh + * @author Matthew Wagerfield + */ +FSS.Mesh = function(geometry, material) { + FSS.Object.call(this); + this.geometry = geometry || new FSS.Geometry(); + this.material = material || new FSS.Material(); + this.side = FSS.FRONT; + this.visible = true; +}; + +FSS.Mesh.prototype = Object.create(FSS.Object.prototype); + +FSS.Mesh.prototype.update = function(lights, calculate) { + var t,triangle, l,light, illuminance; + + // Update Geometry + this.geometry.update(); + + // Calculate the triangle colors + if (calculate) { + + // Iterate through Triangles + for (t = this.geometry.triangles.length - 1; t >= 0; t--) { + triangle = this.geometry.triangles[t]; + + // Reset Triangle Color + FSS.Vector4.set(triangle.color.rgba); + + // Iterate through Lights + for (l = lights.length - 1; l >= 0; l--) { + light = lights[l]; + + // Calculate Illuminance + FSS.Vector3.subtractVectors(light.ray, light.position, triangle.centroid); + FSS.Vector3.normalise(light.ray); + illuminance = FSS.Vector3.dot(triangle.normal, light.ray); + if (this.side === FSS.FRONT) { + illuminance = Math.max(illuminance, 0); + } else if (this.side === FSS.BACK) { + illuminance = Math.abs(Math.min(illuminance, 0)); + } else if (this.side === FSS.DOUBLE) { + illuminance = Math.max(Math.abs(illuminance), 0); + } + + // Calculate Ambient Light + FSS.Vector4.multiplyVectors(triangle.material.slave.rgba, triangle.material.ambient.rgba, light.ambient.rgba); + FSS.Vector4.add(triangle.color.rgba, triangle.material.slave.rgba); + + // Calculate Diffuse Light + FSS.Vector4.multiplyVectors(triangle.material.slave.rgba, triangle.material.diffuse.rgba, light.diffuse.rgba); + FSS.Vector4.multiplyScalar(triangle.material.slave.rgba, illuminance); + FSS.Vector4.add(triangle.color.rgba, triangle.material.slave.rgba); + } + + // Clamp & Format Color + FSS.Vector4.clamp(triangle.color.rgba, 0, 1); + } + } + return this; +}; + +/** + * @class Scene + * @author Matthew Wagerfield + */ +FSS.Scene = function() { + this.meshes = []; + this.lights = []; +}; + +FSS.Scene.prototype = { + add: function(object) { + if (object instanceof FSS.Mesh && !~this.meshes.indexOf(object)) { + this.meshes.push(object); + } else if (object instanceof FSS.Light && !~this.lights.indexOf(object)) { + this.lights.push(object); + } + return this; + }, + remove: function(object) { + if (object instanceof FSS.Mesh && ~this.meshes.indexOf(object)) { + this.meshes.splice(this.meshes.indexOf(object), 1); + } else if (object instanceof FSS.Light && ~this.lights.indexOf(object)) { + this.lights.splice(this.lights.indexOf(object), 1); + } + return this; + } +}; + +/** + * @class Renderer + * @author Matthew Wagerfield + */ +FSS.Renderer = function() { + this.width = 0; + this.height = 0; + this.halfWidth = 0; + this.halfHeight = 0; +}; + +FSS.Renderer.prototype = { + setSize: function(width, height) { + if (this.width === width && this.height === height) return; + this.width = width; + this.height = height; + this.halfWidth = this.width * 0.5; + this.halfHeight = this.height * 0.5; + return this; + }, + clear: function() { + return this; + }, + render: function(scene) { + return this; + } +}; + +/** + * @class SVG Renderer + * @author Matthew Wagerfield + */ +FSS.SVGRenderer = function(s) { + FSS.Renderer.call(this); + this.element = s.g(); +}; + +FSS.SVGRenderer.prototype = Object.create(FSS.Renderer.prototype); + +FSS.SVGRenderer.prototype.setSize = function(width, height) { + FSS.Renderer.prototype.setSize.call(this, width, height); + return this; +}; + +FSS.SVGRenderer.prototype.clear = function() { + FSS.Renderer.prototype.clear.call(this); + for (var i = this.element.childNodes.length - 1; i >= 0; i--) { + this.element.removeChild(this.element.childNodes[i]); + } + return this; +}; + +FSS.SVGRenderer.prototype.render = function(scene) { + FSS.Renderer.prototype.render.call(this, scene); + var m,mesh, t,triangle, points, style; + + // Update Meshes + for (m = scene.meshes.length - 1; m >= 0; m--) { + mesh = scene.meshes[m]; + if (mesh.visible) { + mesh.update(scene.lights, true); + + // Render Triangles + for (t = mesh.geometry.triangles.length - 1; t >= 0; t--) { + triangle = mesh.geometry.triangles[t]; + + if (triangle.polygon.parent() !== this.element) { + this.element.append(triangle.polygon); + } + + points = this.formatPoint(triangle.a)+' '; + points += this.formatPoint(triangle.b)+' '; + points += this.formatPoint(triangle.c); + style = this.formatStyle(triangle.color.format()); + + triangle.polygon.attr({ + points: points, + style: style + }); + } + } + } + return this; +}; + +FSS.SVGRenderer.prototype.formatPoint = function(vertex) { + return (this.halfWidth+vertex.position[0])+','+(this.halfHeight-vertex.position[1]); +}; + +FSS.SVGRenderer.prototype.formatStyle = function(color) { + var style = 'fill:'+color+';'; + style += 'stroke:'+color+';'; + return style; +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Color.js b/demos/snap-ad/src/js/vendor/fss/Color.js new file mode 100755 index 0000000..2f0649f --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Color.js @@ -0,0 +1,34 @@ +/** + * @class Color + * @author Matthew Wagerfield + */ +FSS.Color = function(hex, opacity) { + this.rgba = FSS.Vector4.create(); + this.hex = hex || '#000000'; + this.opacity = FSS.Utils.isNumber(opacity) ? opacity : 1; + this.set(this.hex, this.opacity); +}; + +FSS.Color.prototype = { + set: function(hex, opacity) { + hex = hex.replace('#', ''); + var size = hex.length / 3; + this.rgba[0] = parseInt(hex.substring(size*0, size*1), 16) / 255; + this.rgba[1] = parseInt(hex.substring(size*1, size*2), 16) / 255; + this.rgba[2] = parseInt(hex.substring(size*2, size*3), 16) / 255; + this.rgba[3] = FSS.Utils.isNumber(opacity) ? opacity : this.rgba[3]; + return this; + }, + hexify: function(channel) { + var hex = Math.ceil(channel*255).toString(16); + if (hex.length === 1) { hex = '0' + hex; } + return hex; + }, + format: function() { + var r = this.hexify(this.rgba[0]); + var g = this.hexify(this.rgba[1]); + var b = this.hexify(this.rgba[2]); + this.hex = '#' + r + g + b; + return this.hex; + } +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Core.js b/demos/snap-ad/src/js/vendor/fss/Core.js new file mode 100755 index 0000000..2c26e1c --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Core.js @@ -0,0 +1,61 @@ +/** + * Defines the Flat Surface Shader namespace for all the awesomeness to exist upon. + * @author Matthew Wagerfield + */ +FSS = { + FRONT : 0, + BACK : 1, + DOUBLE : 2, + SVGNS : 'http://www.w3.org/2000/svg' +}; + +/** + * @class Array + * @author Matthew Wagerfield + */ +FSS.Array = typeof Float32Array === 'function' ? Float32Array : Array; + +/** + * @class Utils + * @author Matthew Wagerfield + */ +FSS.Utils = { + isNumber: function(value) { + return !isNaN(parseFloat(value)) && isFinite(value); + } +}; + +/** + * Request Animation Frame Polyfill. + * @author Paul Irish + * @see https://gist.github.com/paulirish/1579671 + */ +(function() { + + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function(callback, element) { + var currentTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currentTime - lastTime)); + var id = window.setTimeout(function() { + callback(currentTime + timeToCall); + }, timeToCall); + lastTime = currentTime + timeToCall; + return id; + }; + } + + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; + } + +}()); diff --git a/demos/snap-ad/src/js/vendor/fss/Geometry.js b/demos/snap-ad/src/js/vendor/fss/Geometry.js new file mode 100755 index 0000000..f7bf62e --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Geometry.js @@ -0,0 +1,24 @@ +/** + * @class Geometry + * @author Matthew Wagerfield + */ +FSS.Geometry = function() { + this.vertices = []; + this.triangles = []; + this.dirty = false; +}; + +FSS.Geometry.prototype = { + update: function() { + if (this.dirty) { + var t,triangle; + for (t = this.triangles.length - 1; t >= 0; t--) { + triangle = this.triangles[t]; + triangle.computeCentroid(); + triangle.computeNormal(); + } + this.dirty = false; + } + return this; + } +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Light.js b/demos/snap-ad/src/js/vendor/fss/Light.js new file mode 100755 index 0000000..8c7e27f --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Light.js @@ -0,0 +1,12 @@ +/** + * @class Light + * @author Matthew Wagerfield + */ +FSS.Light = function(ambient, diffuse) { + FSS.Object.call(this); + this.ambient = new FSS.Color(ambient || '#FFFFFF'); + this.diffuse = new FSS.Color(diffuse || '#FFFFFF'); + this.ray = FSS.Vector3.create(); +}; + +FSS.Light.prototype = Object.create(FSS.Object.prototype); diff --git a/demos/snap-ad/src/js/vendor/fss/Material.js b/demos/snap-ad/src/js/vendor/fss/Material.js new file mode 100755 index 0000000..a6fcb08 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Material.js @@ -0,0 +1,9 @@ +/** + * @class Material + * @author Matthew Wagerfield + */ +FSS.Material = function(ambient, diffuse) { + this.ambient = new FSS.Color(ambient || '#444444'); + this.diffuse = new FSS.Color(diffuse || '#FFFFFF'); + this.slave = new FSS.Color(); +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Math.js b/demos/snap-ad/src/js/vendor/fss/Math.js new file mode 100755 index 0000000..fae7798 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Math.js @@ -0,0 +1,14 @@ +/** + * @object Math Augmentation + * @author Matthew Wagerfield + */ +Math.PIM2 = Math.PI*2; +Math.PID2 = Math.PI/2; +Math.randomInRange = function(min, max) { + return min + (max - min) * Math.random(); +}; +Math.clamp = function(value, min, max) { + value = Math.max(value, min); + value = Math.min(value, max); + return value; +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Mesh.js b/demos/snap-ad/src/js/vendor/fss/Mesh.js new file mode 100755 index 0000000..a02ef65 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Mesh.js @@ -0,0 +1,62 @@ +/** + * @class Mesh + * @author Matthew Wagerfield + */ +FSS.Mesh = function(geometry, material) { + FSS.Object.call(this); + this.geometry = geometry || new FSS.Geometry(); + this.material = material || new FSS.Material(); + this.side = FSS.FRONT; + this.visible = true; +}; + +FSS.Mesh.prototype = Object.create(FSS.Object.prototype); + +FSS.Mesh.prototype.update = function(lights, calculate) { + var t,triangle, l,light, illuminance; + + // Update Geometry + this.geometry.update(); + + // Calculate the triangle colors + if (calculate) { + + // Iterate through Triangles + for (t = this.geometry.triangles.length - 1; t >= 0; t--) { + triangle = this.geometry.triangles[t]; + + // Reset Triangle Color + FSS.Vector4.set(triangle.color.rgba); + + // Iterate through Lights + for (l = lights.length - 1; l >= 0; l--) { + light = lights[l]; + + // Calculate Illuminance + FSS.Vector3.subtractVectors(light.ray, light.position, triangle.centroid); + FSS.Vector3.normalise(light.ray); + illuminance = FSS.Vector3.dot(triangle.normal, light.ray); + if (this.side === FSS.FRONT) { + illuminance = Math.max(illuminance, 0); + } else if (this.side === FSS.BACK) { + illuminance = Math.abs(Math.min(illuminance, 0)); + } else if (this.side === FSS.DOUBLE) { + illuminance = Math.max(Math.abs(illuminance), 0); + } + + // Calculate Ambient Light + FSS.Vector4.multiplyVectors(this.material.slave.rgba, this.material.ambient.rgba, light.ambient.rgba); + FSS.Vector4.add(triangle.color.rgba, this.material.slave.rgba); + + // Calculate Diffuse Light + FSS.Vector4.multiplyVectors(this.material.slave.rgba, this.material.diffuse.rgba, light.diffuse.rgba); + FSS.Vector4.multiplyScalar(this.material.slave.rgba, illuminance); + FSS.Vector4.add(triangle.color.rgba, this.material.slave.rgba); + } + + // Clamp & Format Color + FSS.Vector4.clamp(triangle.color.rgba, 0, 1); + } + } + return this; +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Object.js b/demos/snap-ad/src/js/vendor/fss/Object.js new file mode 100755 index 0000000..19255d3 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Object.js @@ -0,0 +1,14 @@ +/** + * @class Object + * @author Matthew Wagerfield + */ +FSS.Object = function() { + this.position = FSS.Vector3.create(); +}; + +FSS.Object.prototype = { + setPosition: function(x, y, z) { + FSS.Vector3.set(this.position, x, y, z); + return this; + } +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Plane.js b/demos/snap-ad/src/js/vendor/fss/Plane.js new file mode 100755 index 0000000..c7598c0 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Plane.js @@ -0,0 +1,44 @@ +/** + * @class Plane + * @author Matthew Wagerfield + */ +FSS.Plane = function(width, height, segments, slices, s) { + FSS.Geometry.call(this); + this.width = width || 100; + this.height = height || 100; + this.segments = segments || 4; + this.slices = slices || 4; + this.segmentWidth = this.width / this.segments; + this.sliceHeight = this.height / this.slices; + + // Cache Variables + var x, y, v0, v1, v2, v3, + vertex, triangle, vertices = [], + offsetX = this.width * -0.5, + offsetY = this.height * 0.5; + + // Add Vertices + for (x = 0; x <= this.segments; x++) { + vertices.push([]); + for (y = 0; y <= this.slices; y++) { + vertex = new FSS.Vertex(offsetX + x*this.segmentWidth, offsetY - y*this.sliceHeight); + vertices[x].push(vertex); + this.vertices.push(vertex); + } + } + + // Add Triangles + for (x = 0; x < this.segments; x++) { + for (y = 0; y < this.slices; y++) { + v0 = vertices[x+0][y+0]; + v1 = vertices[x+0][y+1]; + v2 = vertices[x+1][y+0]; + v3 = vertices[x+1][y+1]; + t0 = new FSS.Triangle(v0, v1, v2, s); + t1 = new FSS.Triangle(v2, v1, v3, s); + this.triangles.push(t0, t1); + } + } +}; + +FSS.Plane.prototype = Object.create(FSS.Geometry.prototype); diff --git a/demos/snap-ad/src/js/vendor/fss/Renderer.js b/demos/snap-ad/src/js/vendor/fss/Renderer.js new file mode 100755 index 0000000..aebac17 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Renderer.js @@ -0,0 +1,27 @@ +/** + * @class Renderer + * @author Matthew Wagerfield + */ +FSS.Renderer = function() { + this.width = 0; + this.height = 0; + this.halfWidth = 0; + this.halfHeight = 0; +}; + +FSS.Renderer.prototype = { + setSize: function(width, height) { + if (this.width === width && this.height === height) return; + this.width = width; + this.height = height; + this.halfWidth = this.width * 0.5; + this.halfHeight = this.height * 0.5; + return this; + }, + clear: function() { + return this; + }, + render: function(scene) { + return this; + } +}; diff --git a/demos/snap-ad/src/js/vendor/fss/SVGRenderer.js b/demos/snap-ad/src/js/vendor/fss/SVGRenderer.js new file mode 100755 index 0000000..aa226e9 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/SVGRenderer.js @@ -0,0 +1,66 @@ +/** + * @class SVG Renderer + * @author Matthew Wagerfield + */ +FSS.SVGRenderer = function(s) { + FSS.Renderer.call(this); + this.element = s.g(); +}; + +FSS.SVGRenderer.prototype = Object.create(FSS.Renderer.prototype); + +FSS.SVGRenderer.prototype.setSize = function(width, height) { + FSS.Renderer.prototype.setSize.call(this, width, height); + return this; +}; + +FSS.SVGRenderer.prototype.clear = function() { + FSS.Renderer.prototype.clear.call(this); + for (var i = this.element.childNodes.length - 1; i >= 0; i--) { + this.element.removeChild(this.element.childNodes[i]); + } + return this; +}; + +FSS.SVGRenderer.prototype.render = function(scene) { + FSS.Renderer.prototype.render.call(this, scene); + var m,mesh, t,triangle, points, style; + + // Update Meshes + for (m = scene.meshes.length - 1; m >= 0; m--) { + mesh = scene.meshes[m]; + if (mesh.visible) { + mesh.update(scene.lights, true); + + // Render Triangles + for (t = mesh.geometry.triangles.length - 1; t >= 0; t--) { + triangle = mesh.geometry.triangles[t]; + + if (triangle.polygon.parent() !== this.element) { + this.element.append(triangle.polygon); + } + + points = this.formatPoint(triangle.a)+' '; + points += this.formatPoint(triangle.b)+' '; + points += this.formatPoint(triangle.c); + style = this.formatStyle(triangle.color.format()); + + triangle.polygon.attr({ + points: points, + style: style + }); + } + } + } + return this; +}; + +FSS.SVGRenderer.prototype.formatPoint = function(vertex) { + return (this.halfWidth+vertex.position[0])+','+(this.halfHeight-vertex.position[1]); +}; + +FSS.SVGRenderer.prototype.formatStyle = function(color) { + var style = 'fill:'+color+';'; + style += 'stroke:'+color+';'; + return style; +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Scene.js b/demos/snap-ad/src/js/vendor/fss/Scene.js new file mode 100755 index 0000000..50f1dc6 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Scene.js @@ -0,0 +1,27 @@ +/** + * @class Scene + * @author Matthew Wagerfield + */ +FSS.Scene = function() { + this.meshes = []; + this.lights = []; +}; + +FSS.Scene.prototype = { + add: function(object) { + if (object instanceof FSS.Mesh && !~this.meshes.indexOf(object)) { + this.meshes.push(object); + } else if (object instanceof FSS.Light && !~this.lights.indexOf(object)) { + this.lights.push(object); + } + return this; + }, + remove: function(object) { + if (object instanceof FSS.Mesh && ~this.meshes.indexOf(object)) { + this.meshes.splice(this.meshes.indexOf(object), 1); + } else if (object instanceof FSS.Light && ~this.lights.indexOf(object)) { + this.lights.splice(this.lights.indexOf(object), 1); + } + return this; + } +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Triangle.js b/demos/snap-ad/src/js/vendor/fss/Triangle.js new file mode 100755 index 0000000..23cf4da --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Triangle.js @@ -0,0 +1,41 @@ +/** + * @class Triangle + * @author Matthew Wagerfield + */ +FSS.Triangle = function(a, b, c, s) { + this.a = a || new FSS.Vertex(); + this.b = b || new FSS.Vertex(); + this.c = c || new FSS.Vertex(); + this.vertices = [this.a, this.b, this.c]; + this.u = FSS.Vector3.create(); + this.v = FSS.Vector3.create(); + this.centroid = FSS.Vector3.create(); + this.normal = FSS.Vector3.create(); + this.color = new FSS.Color(); + this.polygon = s.polygon(); + this.polygon.attr({ + 'stroke-linejoin': 'round', + 'stroke-miterlimit': 1, + 'stroke-width': 1 + }); + + this.computeCentroid(); + this.computeNormal(); +}; + +FSS.Triangle.prototype = { + computeCentroid: function() { + this.centroid[0] = this.a.position[0] + this.b.position[0] + this.c.position[0]; + this.centroid[1] = this.a.position[1] + this.b.position[1] + this.c.position[1]; + this.centroid[2] = this.a.position[2] + this.b.position[2] + this.c.position[2]; + FSS.Vector3.divideScalar(this.centroid, 3); + return this; + }, + computeNormal: function() { + FSS.Vector3.subtractVectors(this.u, this.b.position, this.a.position); + FSS.Vector3.subtractVectors(this.v, this.c.position, this.a.position); + FSS.Vector3.crossVectors(this.normal, this.u, this.v); + FSS.Vector3.normalise(this.normal); + return this; + } +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Vector3.js b/demos/snap-ad/src/js/vendor/fss/Vector3.js new file mode 100755 index 0000000..93787ac --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Vector3.js @@ -0,0 +1,190 @@ +/** + * @object Vector3 + * @author Matthew Wagerfield + */ +FSS.Vector3 = { + create: function(x, y, z) { + var vector = new FSS.Array(3); + this.set(vector, x, y, z); + return vector; + }, + clone: function(a) { + var vector = this.create(); + this.copy(vector, a); + return vector; + }, + set: function(target, x, y, z) { + target[0] = x || 0; + target[1] = y || 0; + target[2] = z || 0; + return this; + }, + setX: function(target, x) { + target[0] = x || 0; + return this; + }, + setY: function(target, y) { + target[1] = y || 0; + return this; + }, + setZ: function(target, z) { + target[2] = z || 0; + return this; + }, + copy: function(target, a) { + target[0] = a[0]; + target[1] = a[1]; + target[2] = a[2]; + return this; + }, + add: function(target, a) { + target[0] += a[0]; + target[1] += a[1]; + target[2] += a[2]; + return this; + }, + addVectors: function(target, a, b) { + target[0] = a[0] + b[0]; + target[1] = a[1] + b[1]; + target[2] = a[2] + b[2]; + return this; + }, + addScalar: function(target, s) { + target[0] += s; + target[1] += s; + target[2] += s; + return this; + }, + subtract: function(target, a) { + target[0] -= a[0]; + target[1] -= a[1]; + target[2] -= a[2]; + return this; + }, + subtractVectors: function(target, a, b) { + target[0] = a[0] - b[0]; + target[1] = a[1] - b[1]; + target[2] = a[2] - b[2]; + return this; + }, + subtractScalar: function(target, s) { + target[0] -= s; + target[1] -= s; + target[2] -= s; + return this; + }, + multiply: function(target, a) { + target[0] *= a[0]; + target[1] *= a[1]; + target[2] *= a[2]; + return this; + }, + multiplyVectors: function(target, a, b) { + target[0] = a[0] * b[0]; + target[1] = a[1] * b[1]; + target[2] = a[2] * b[2]; + return this; + }, + multiplyScalar: function(target, s) { + target[0] *= s; + target[1] *= s; + target[2] *= s; + return this; + }, + divide: function(target, a) { + target[0] /= a[0]; + target[1] /= a[1]; + target[2] /= a[2]; + return this; + }, + divideVectors: function(target, a, b) { + target[0] = a[0] / b[0]; + target[1] = a[1] / b[1]; + target[2] = a[2] / b[2]; + return this; + }, + divideScalar: function(target, s) { + if (s !== 0) { + target[0] /= s; + target[1] /= s; + target[2] /= s; + } else { + target[0] = 0; + target[1] = 0; + target[2] = 0; + } + return this; + }, + cross: function(target, a) { + var x = target[0]; + var y = target[1]; + var z = target[2]; + target[0] = y*a[2] - z*a[1]; + target[1] = z*a[0] - x*a[2]; + target[2] = x*a[1] - y*a[0]; + return this; + }, + crossVectors: function(target, a, b) { + target[0] = a[1]*b[2] - a[2]*b[1]; + target[1] = a[2]*b[0] - a[0]*b[2]; + target[2] = a[0]*b[1] - a[1]*b[0]; + return this; + }, + min: function(target, value) { + if (target[0] < value) { target[0] = value; } + if (target[1] < value) { target[1] = value; } + if (target[2] < value) { target[2] = value; } + return this; + }, + max: function(target, value) { + if (target[0] > value) { target[0] = value; } + if (target[1] > value) { target[1] = value; } + if (target[2] > value) { target[2] = value; } + return this; + }, + clamp: function(target, min, max) { + this.min(target, min); + this.max(target, max); + return this; + }, + limit: function(target, min, max) { + var length = this.length(target); + if (min !== null && length < min) { + this.setLength(target, min); + } else if (max !== null && length > max) { + this.setLength(target, max); + } + return this; + }, + dot: function(a, b) { + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; + }, + normalise: function(target) { + return this.divideScalar(target, this.length(target)); + }, + negate: function(target) { + return this.multiplyScalar(target, -1); + }, + distanceSquared: function(a, b) { + var dx = a[0] - b[0]; + var dy = a[1] - b[1]; + var dz = a[2] - b[2]; + return dx*dx + dy*dy + dz*dz; + }, + distance: function(a, b) { + return Math.sqrt(this.distanceSquared(a, b)); + }, + lengthSquared: function(a) { + return a[0]*a[0] + a[1]*a[1] + a[2]*a[2]; + }, + length: function(a) { + return Math.sqrt(this.lengthSquared(a)); + }, + setLength: function(target, l) { + var length = this.length(target); + if (length !== 0 && l !== length) { + this.multiplyScalar(target, l / length); + } + return this; + } +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Vector4.js b/demos/snap-ad/src/js/vendor/fss/Vector4.js new file mode 100755 index 0000000..1004cb2 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Vector4.js @@ -0,0 +1,74 @@ +/** + * @object Vector4 + * @author Matthew Wagerfield + */ +FSS.Vector4 = { + create: function(x, y, z, w) { + var vector = new FSS.Array(4); + this.set(vector, x, y, z); + return vector; + }, + set: function(target, x, y, z, w) { + target[0] = x || 0; + target[1] = y || 0; + target[2] = z || 0; + target[3] = w || 0; + return this; + }, + setX: function(target, x) { + target[0] = x || 0; + return this; + }, + setY: function(target, y) { + target[1] = y || 0; + return this; + }, + setZ: function(target, z) { + target[2] = z || 0; + return this; + }, + setW: function(target, w) { + target[3] = w || 0; + return this; + }, + add: function(target, a) { + target[0] += a[0]; + target[1] += a[1]; + target[2] += a[2]; + target[3] += a[3]; + return this; + }, + multiplyVectors: function(target, a, b) { + target[0] = a[0] * b[0]; + target[1] = a[1] * b[1]; + target[2] = a[2] * b[2]; + target[3] = a[3] * b[3]; + return this; + }, + multiplyScalar: function(target, s) { + target[0] *= s; + target[1] *= s; + target[2] *= s; + target[3] *= s; + return this; + }, + min: function(target, value) { + if (target[0] < value) { target[0] = value; } + if (target[1] < value) { target[1] = value; } + if (target[2] < value) { target[2] = value; } + if (target[3] < value) { target[3] = value; } + return this; + }, + max: function(target, value) { + if (target[0] > value) { target[0] = value; } + if (target[1] > value) { target[1] = value; } + if (target[2] > value) { target[2] = value; } + if (target[3] > value) { target[3] = value; } + return this; + }, + clamp: function(target, min, max) { + this.min(target, min); + this.max(target, max); + return this; + } +}; diff --git a/demos/snap-ad/src/js/vendor/fss/Vertex.js b/demos/snap-ad/src/js/vendor/fss/Vertex.js new file mode 100755 index 0000000..58b9c58 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/fss/Vertex.js @@ -0,0 +1,14 @@ +/** + * @class Vertex + * @author Matthew Wagerfield + */ +FSS.Vertex = function(x, y, z) { + this.position = FSS.Vector3.create(x, y, z); +}; + +FSS.Vertex.prototype = { + setPosition: function(x, y, z) { + FSS.Vector3.set(this.position, x, y, z); + return this; + } +}; diff --git a/demos/snap-ad/src/js/vendor/modernizr.min.js b/demos/snap-ad/src/js/vendor/modernizr.min.js new file mode 100644 index 0000000..02fb48a --- /dev/null +++ b/demos/snap-ad/src/js/vendor/modernizr.min.js @@ -0,0 +1,4 @@ +/* Modernizr 2.7.1 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-shiv-cssclasses-load + */ +;window.Modernizr=function(a,b,c){function u(a){j.cssText=a}function v(a,b){return u(prefixes.join(a+";")+(b||""))}function w(a,b){return typeof a===b}function x(a,b){return!!~(""+a).indexOf(b)}function y(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:w(f,"function")?f.bind(d||b):f}return!1}var d="2.7.1",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m={},n={},o={},p=[],q=p.slice,r,s={}.hasOwnProperty,t;!w(s,"undefined")&&!w(s.call,"undefined")?t=function(a,b){return s.call(a,b)}:t=function(a,b){return b in a&&w(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=q.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(q.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(q.call(arguments)))};return e});for(var z in m)t(m,z)&&(r=z.toLowerCase(),e[r]=m[z](),p.push((e[r]?"":"no-")+r));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)t(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},u(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+p.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f -1; i -= 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop); + } + + function getOwn(obj, prop) { + return hasProp(obj, prop) && obj[prop]; + } + + /** + * Cycles over properties in an object and calls a function for each + * property value. If the function returns a truthy value, then the + * iteration is stopped. + */ + function eachProp(obj, func) { + var prop; + for (prop in obj) { + if (hasProp(obj, prop)) { + if (func(obj[prop], prop)) { + break; + } + } + } + } + + /** + * Simple function to mix in properties from source into target, + * but only if target does not already have a property of the same name. + */ + function mixin(target, source, force, deepStringMixin) { + if (source) { + eachProp(source, function (value, prop) { + if (force || !hasProp(target, prop)) { + if (deepStringMixin && typeof value !== 'string') { + if (!target[prop]) { + target[prop] = {}; + } + mixin(target[prop], value, force, deepStringMixin); + } else { + target[prop] = value; + } + } + }); + } + return target; + } + + //Similar to Function.prototype.bind, but the 'this' object is specified + //first, since it is easier to read/figure out what 'this' will be. + function bind(obj, fn) { + return function () { + return fn.apply(obj, arguments); + }; + } + + function scripts() { + return document.getElementsByTagName('script'); + } + + //Allow getting a global that expressed in + //dot notation, like 'a.b.c'. + function getGlobal(value) { + if (!value) { + return value; + } + var g = global; + each(value.split('.'), function (part) { + g = g[part]; + }); + return g; + } + + /** + * Constructs an error with a pointer to an URL with more information. + * @param {String} id the error ID that maps to an ID on a web page. + * @param {String} message human readable error. + * @param {Error} [err] the original error, if there is one. + * + * @returns {Error} + */ + function makeError(id, msg, err, requireModules) { + var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); + e.requireType = id; + e.requireModules = requireModules; + if (err) { + e.originalError = err; + } + return e; + } + + if (typeof define !== 'undefined') { + //If a define is already in play via another AMD loader, + //do not overwrite. + return; + } + + if (typeof requirejs !== 'undefined') { + if (isFunction(requirejs)) { + //Do not overwrite and existing requirejs instance. + return; + } + cfg = requirejs; + requirejs = undefined; + } + + //Allow for a require config object + if (typeof require !== 'undefined' && !isFunction(require)) { + //assume it is a config object. + cfg = require; + require = undefined; + } + + function newContext(contextName) { + var inCheckLoaded, Module, context, handlers, + checkLoadedTimeoutId, + config = { + //Defaults. Do not set a default for map + //config to speed up normalize(), which + //will run faster if there is no default. + waitSeconds: 7, + baseUrl: './', + paths: {}, + pkgs: {}, + shim: {}, + config: {} + }, + registry = {}, + //registry of just enabled modules, to speed + //cycle breaking code when lots of modules + //are registered, but not activated. + enabledRegistry = {}, + undefEvents = {}, + defQueue = [], + defined = {}, + urlFetched = {}, + requireCounter = 1, + unnormalizedCounter = 1; + + /** + * Trims the . and .. from an array of path segments. + * It will keep a leading path segment if a .. will become + * the first path segment, to help with module name lookups, + * which act like paths, but can be remapped. But the end result, + * all paths that use this function should look normalized. + * NOTE: this method MODIFIES the input array. + * @param {Array} ary the array of path segments. + */ + function trimDots(ary) { + var i, part; + for (i = 0; ary[i]; i += 1) { + part = ary[i]; + if (part === '.') { + ary.splice(i, 1); + i -= 1; + } else if (part === '..') { + if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { + //End of the line. Keep at least one non-dot + //path segment at the front so it can be mapped + //correctly to disk. Otherwise, there is likely + //no path mapping for a path starting with '..'. + //This can still fail, but catches the most reasonable + //uses of .. + break; + } else if (i > 0) { + ary.splice(i - 1, 2); + i -= 2; + } + } + } + } + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @param {Boolean} applyMap apply the map config to the value. Should + * only be done if this normalization is for a dependency ID. + * @returns {String} normalized name + */ + function normalize(name, baseName, applyMap) { + var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment, + foundMap, foundI, foundStarMap, starI, + baseParts = baseName && baseName.split('/'), + normalizedBaseParts = baseParts, + map = config.map, + starMap = map && map['*']; + + //Adjust any relative paths. + if (name && name.charAt(0) === '.') { + //If have a base name, try to normalize against it, + //otherwise, assume it is a top-level require that will + //be relative to baseUrl in the end. + if (baseName) { + if (getOwn(config.pkgs, baseName)) { + //If the baseName is a package name, then just treat it as one + //name to concat the name with. + normalizedBaseParts = baseParts = [baseName]; + } else { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); + } + + name = normalizedBaseParts.concat(name.split('/')); + trimDots(name); + + //Some use of packages may use a . path to reference the + //'main' module name, so normalize for that. + pkgConfig = getOwn(config.pkgs, (pkgName = name[0])); + name = name.join('/'); + if (pkgConfig && name === pkgName + '/' + pkgConfig.main) { + name = pkgName; + } + } else if (name.indexOf('./') === 0) { + // No baseName, so this is ID is resolved relative + // to baseUrl, pull off the leading dot. + name = name.substring(2); + } + } + + //Apply map config if available. + if (applyMap && map && (baseParts || starMap)) { + nameParts = name.split('/'); + + for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join('/'); + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = getOwn(mapValue, nameSegment); + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue; + foundI = i; + break; + } + } + } + } + + if (foundMap) { + break; + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { + foundStarMap = getOwn(starMap, nameSegment); + starI = i; + } + } + + if (!foundMap && foundStarMap) { + foundMap = foundStarMap; + foundI = starI; + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap); + name = nameParts.join('/'); + } + } + + return name; + } + + function removeScript(name) { + if (isBrowser) { + each(scripts(), function (scriptNode) { + if (scriptNode.getAttribute('data-requiremodule') === name && + scriptNode.getAttribute('data-requirecontext') === context.contextName) { + scriptNode.parentNode.removeChild(scriptNode); + return true; + } + }); + } + } + + function hasPathFallback(id) { + var pathConfig = getOwn(config.paths, id); + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { + removeScript(id); + //Pop off the first array value, since it failed, and + //retry + pathConfig.shift(); + context.require.undef(id); + context.require([id]); + return true; + } + } + + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1; + if (index > -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + return [prefix, name]; + } + + /** + * Creates a module mapping that includes plugin prefix, module + * name, and path. If parentModuleMap is provided it will + * also normalize the name via require.normalize() + * + * @param {String} name the module name + * @param {String} [parentModuleMap] parent module map + * for the module name, used to resolve relative names. + * @param {Boolean} isNormalized: is the ID already normalized. + * This is true if this call is done for a define() module ID. + * @param {Boolean} applyMap: apply the map config to the ID. + * Should only be true if this map is for a dependency. + * + * @returns {Object} + */ + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { + var url, pluginModule, suffix, nameParts, + prefix = null, + parentName = parentModuleMap ? parentModuleMap.name : null, + originalName = name, + isDefine = true, + normalizedName = ''; + + //If no name, then it means it is a require call, generate an + //internal name. + if (!name) { + isDefine = false; + name = '_@r' + (requireCounter += 1); + } + + nameParts = splitPrefix(name); + prefix = nameParts[0]; + name = nameParts[1]; + + if (prefix) { + prefix = normalize(prefix, parentName, applyMap); + pluginModule = getOwn(defined, prefix); + } + + //Account for relative paths if there is a base name. + if (name) { + if (prefix) { + if (pluginModule && pluginModule.normalize) { + //Plugin is loaded, use its normalize method. + normalizedName = pluginModule.normalize(name, function (name) { + return normalize(name, parentName, applyMap); + }); + } else { + normalizedName = normalize(name, parentName, applyMap); + } + } else { + //A regular module. + normalizedName = normalize(name, parentName, applyMap); + + //Normalized name may be a plugin ID due to map config + //application in normalize. The map config values must + //already be normalized, so do not need to redo that part. + nameParts = splitPrefix(normalizedName); + prefix = nameParts[0]; + normalizedName = nameParts[1]; + isNormalized = true; + + url = context.nameToUrl(normalizedName); + } + } + + //If the id is a plugin id that cannot be determined if it needs + //normalization, stamp it with a unique ID so two matching relative + //ids that may conflict can be separate. + suffix = prefix && !pluginModule && !isNormalized ? + '_unnormalized' + (unnormalizedCounter += 1) : + ''; + + return { + prefix: prefix, + name: normalizedName, + parentMap: parentModuleMap, + unnormalized: !!suffix, + url: url, + originalName: originalName, + isDefine: isDefine, + id: (prefix ? + prefix + '!' + normalizedName : + normalizedName) + suffix + }; + } + + function getModule(depMap) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (!mod) { + mod = registry[id] = new context.Module(depMap); + } + + return mod; + } + + function on(depMap, name, fn) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (hasProp(defined, id) && + (!mod || mod.defineEmitComplete)) { + if (name === 'defined') { + fn(defined[id]); + } + } else { + getModule(depMap).on(name, fn); + } + } + + function onError(err, errback) { + var ids = err.requireModules, + notified = false; + + if (errback) { + errback(err); + } else { + each(ids, function (id) { + var mod = getOwn(registry, id); + if (mod) { + //Set error on module, so it skips timeout checks. + mod.error = err; + if (mod.events.error) { + notified = true; + mod.emit('error', err); + } + } + }); + + if (!notified) { + req.onError(err); + } + } + } + + /** + * Internal method to transfer globalQueue items to this context's + * defQueue. + */ + function takeGlobalQueue() { + //Push all the globalDefQueue items into the context's defQueue + if (globalDefQueue.length) { + //Array splice in the values since the context code has a + //local var ref to defQueue, so cannot just reassign the one + //on context. + apsp.apply(defQueue, + [defQueue.length - 1, 0].concat(globalDefQueue)); + globalDefQueue = []; + } + } + + handlers = { + 'require': function (mod) { + if (mod.require) { + return mod.require; + } else { + return (mod.require = context.makeRequire(mod.map)); + } + }, + 'exports': function (mod) { + mod.usingExports = true; + if (mod.map.isDefine) { + if (mod.exports) { + return mod.exports; + } else { + return (mod.exports = defined[mod.map.id] = {}); + } + } + }, + 'module': function (mod) { + if (mod.module) { + return mod.module; + } else { + return (mod.module = { + id: mod.map.id, + uri: mod.map.url, + config: function () { + return (config.config && getOwn(config.config, mod.map.id)) || {}; + }, + exports: defined[mod.map.id] + }); + } + } + }; + + function cleanRegistry(id) { + //Clean up machinery used for waiting modules. + delete registry[id]; + delete enabledRegistry[id]; + } + + function breakCycle(mod, traced, processed) { + var id = mod.map.id; + + if (mod.error) { + mod.emit('error', mod.error); + } else { + traced[id] = true; + each(mod.depMaps, function (depMap, i) { + var depId = depMap.id, + dep = getOwn(registry, depId); + + //Only force things that have not completed + //being defined, so still in the registry, + //and only if it has not been matched up + //in the module already. + if (dep && !mod.depMatched[i] && !processed[depId]) { + if (getOwn(traced, depId)) { + mod.defineDep(i, defined[depId]); + mod.check(); //pass false? + } else { + breakCycle(dep, traced, processed); + } + } + }); + processed[id] = true; + } + } + + function checkLoaded() { + var map, modId, err, usingPathFallback, + waitInterval = config.waitSeconds * 1000, + //It is possible to disable the wait interval by using waitSeconds of 0. + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), + noLoads = [], + reqCalls = [], + stillLoading = false, + needCycleCheck = true; + + //Do not bother if this call was a result of a cycle break. + if (inCheckLoaded) { + return; + } + + inCheckLoaded = true; + + //Figure out the state of all the modules. + eachProp(enabledRegistry, function (mod) { + map = mod.map; + modId = map.id; + + //Skip things that are not enabled or in error state. + if (!mod.enabled) { + return; + } + + if (!map.isDefine) { + reqCalls.push(mod); + } + + if (!mod.error) { + //If the module should be executed, and it has not + //been inited and time is up, remember it. + if (!mod.inited && expired) { + if (hasPathFallback(modId)) { + usingPathFallback = true; + stillLoading = true; + } else { + noLoads.push(modId); + removeScript(modId); + } + } else if (!mod.inited && mod.fetched && map.isDefine) { + stillLoading = true; + if (!map.prefix) { + //No reason to keep looking for unfinished + //loading. If the only stillLoading is a + //plugin resource though, keep going, + //because it may be that a plugin resource + //is waiting on a non-plugin cycle. + return (needCycleCheck = false); + } + } + } + }); + + if (expired && noLoads.length) { + //If wait time expired, throw error of unloaded modules. + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); + err.contextName = context.contextName; + return onError(err); + } + + //Not expired, check for a cycle. + if (needCycleCheck) { + each(reqCalls, function (mod) { + breakCycle(mod, {}, {}); + }); + } + + //If still waiting on loads, and the waiting load is something + //other than a plugin resource, or there are still outstanding + //scripts, then just try back later. + if ((!expired || usingPathFallback) && stillLoading) { + //Something is still waiting to load. Wait for it, but only + //if a timeout is not already in effect. + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { + checkLoadedTimeoutId = setTimeout(function () { + checkLoadedTimeoutId = 0; + checkLoaded(); + }, 50); + } + } + + inCheckLoaded = false; + } + + Module = function (map) { + this.events = getOwn(undefEvents, map.id) || {}; + this.map = map; + this.shim = getOwn(config.shim, map.id); + this.depExports = []; + this.depMaps = []; + this.depMatched = []; + this.pluginMaps = {}; + this.depCount = 0; + + /* this.exports this.factory + this.depMaps = [], + this.enabled, this.fetched + */ + }; + + Module.prototype = { + init: function (depMaps, factory, errback, options) { + options = options || {}; + + //Do not do more inits if already done. Can happen if there + //are multiple define calls for the same module. That is not + //a normal, common case, but it is also not unexpected. + if (this.inited) { + return; + } + + this.factory = factory; + + if (errback) { + //Register for errors on this module. + this.on('error', errback); + } else if (this.events.error) { + //If no errback already, but there are error listeners + //on this module, set up an errback to pass to the deps. + errback = bind(this, function (err) { + this.emit('error', err); + }); + } + + //Do a copy of the dependency array, so that + //source inputs are not modified. For example + //"shim" deps are passed in here directly, and + //doing a direct modification of the depMaps array + //would affect that config. + this.depMaps = depMaps && depMaps.slice(0); + + this.errback = errback; + + //Indicate this module has be initialized + this.inited = true; + + this.ignore = options.ignore; + + //Could have option to init this module in enabled mode, + //or could have been previously marked as enabled. However, + //the dependencies are not known until init is called. So + //if enabled previously, now trigger dependencies as enabled. + if (options.enabled || this.enabled) { + //Enable this module and dependencies. + //Will call this.check() + this.enable(); + } else { + this.check(); + } + }, + + defineDep: function (i, depExports) { + //Because of cycles, defined callback for a given + //export can be called more than once. + if (!this.depMatched[i]) { + this.depMatched[i] = true; + this.depCount -= 1; + this.depExports[i] = depExports; + } + }, + + fetch: function () { + if (this.fetched) { + return; + } + this.fetched = true; + + context.startTime = (new Date()).getTime(); + + var map = this.map; + + //If the manager is for a plugin managed resource, + //ask the plugin to load it now. + if (this.shim) { + context.makeRequire(this.map, { + enableBuildCallback: true + })(this.shim.deps || [], bind(this, function () { + return map.prefix ? this.callPlugin() : this.load(); + })); + } else { + //Regular dependency. + return map.prefix ? this.callPlugin() : this.load(); + } + }, + + load: function () { + var url = this.map.url; + + //Regular dependency. + if (!urlFetched[url]) { + urlFetched[url] = true; + context.load(this.map.id, url); + } + }, + + /** + * Checks if the module is ready to define itself, and if so, + * define it. + */ + check: function () { + if (!this.enabled || this.enabling) { + return; + } + + var err, cjsModule, + id = this.map.id, + depExports = this.depExports, + exports = this.exports, + factory = this.factory; + + if (!this.inited) { + this.fetch(); + } else if (this.error) { + this.emit('error', this.error); + } else if (!this.defining) { + //The factory could trigger another require call + //that would result in checking this module to + //define itself again. If already in the process + //of doing that, skip this work. + this.defining = true; + + if (this.depCount < 1 && !this.defined) { + if (isFunction(factory)) { + //If there is an error listener, favor passing + //to that instead of throwing an error. + if (this.events.error) { + try { + exports = context.execCb(id, factory, depExports, exports); + } catch (e) { + err = e; + } + } else { + exports = context.execCb(id, factory, depExports, exports); + } + + if (this.map.isDefine) { + //If setting exports via 'module' is in play, + //favor that over return value and exports. After that, + //favor a non-undefined return value over exports use. + cjsModule = this.module; + if (cjsModule && + cjsModule.exports !== undefined && + //Make sure it is not already the exports value + cjsModule.exports !== this.exports) { + exports = cjsModule.exports; + } else if (exports === undefined && this.usingExports) { + //exports already set the defined value. + exports = this.exports; + } + } + + if (err) { + err.requireMap = this.map; + err.requireModules = [this.map.id]; + err.requireType = 'define'; + return onError((this.error = err)); + } + + } else { + //Just a literal value + exports = factory; + } + + this.exports = exports; + + if (this.map.isDefine && !this.ignore) { + defined[id] = exports; + + if (req.onResourceLoad) { + req.onResourceLoad(context, this.map, this.depMaps); + } + } + + //Clean up + cleanRegistry(id); + + this.defined = true; + } + + //Finished the define stage. Allow calling check again + //to allow define notifications below in the case of a + //cycle. + this.defining = false; + + if (this.defined && !this.defineEmitted) { + this.defineEmitted = true; + this.emit('defined', this.exports); + this.defineEmitComplete = true; + } + + } + }, + + callPlugin: function () { + var map = this.map, + id = map.id, + //Map already normalized the prefix. + pluginMap = makeModuleMap(map.prefix); + + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(pluginMap); + + on(pluginMap, 'defined', bind(this, function (plugin) { + var load, normalizedMap, normalizedMod, + name = this.map.name, + parentName = this.map.parentMap ? this.map.parentMap.name : null, + localRequire = context.makeRequire(map.parentMap, { + enableBuildCallback: true + }); + + //If current map is not normalized, wait for that + //normalized name to load instead of continuing. + if (this.map.unnormalized) { + //Normalize the ID if the plugin allows it. + if (plugin.normalize) { + name = plugin.normalize(name, function (name) { + return normalize(name, parentName, true); + }) || ''; + } + + //prefix and name should already be normalized, no need + //for applying map config again either. + normalizedMap = makeModuleMap(map.prefix + '!' + name, + this.map.parentMap); + on(normalizedMap, + 'defined', bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true, + ignore: true + }); + })); + + normalizedMod = getOwn(registry, normalizedMap.id); + if (normalizedMod) { + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(normalizedMap); + + if (this.events.error) { + normalizedMod.on('error', bind(this, function (err) { + this.emit('error', err); + })); + } + normalizedMod.enable(); + } + + return; + } + + load = bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true + }); + }); + + load.error = bind(this, function (err) { + this.inited = true; + this.error = err; + err.requireModules = [id]; + + //Remove temp unnormalized modules for this module, + //since they will never be resolved otherwise now. + eachProp(registry, function (mod) { + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { + cleanRegistry(mod.map.id); + } + }); + + onError(err); + }); + + //Allow plugins to load other code without having to know the + //context or how to 'complete' the load. + load.fromText = bind(this, function (text, textAlt) { + /*jslint evil: true */ + var moduleName = map.name, + moduleMap = makeModuleMap(moduleName), + hasInteractive = useInteractive; + + //As of 2.1.0, support just passing the text, to reinforce + //fromText only being called once per resource. Still + //support old style of passing moduleName but discard + //that moduleName in favor of the internal ref. + if (textAlt) { + text = textAlt; + } + + //Turn off interactive script matching for IE for any define + //calls in the text, then turn it back on at the end. + if (hasInteractive) { + useInteractive = false; + } + + //Prime the system by creating a module instance for + //it. + getModule(moduleMap); + + //Transfer any config to this other module. + if (hasProp(config.config, id)) { + config.config[moduleName] = config.config[id]; + } + + try { + req.exec(text); + } catch (e) { + return onError(makeError('fromtexteval', + 'fromText eval for ' + id + + ' failed: ' + e, + e, + [id])); + } + + if (hasInteractive) { + useInteractive = true; + } + + //Mark this as a dependency for the plugin + //resource + this.depMaps.push(moduleMap); + + //Support anonymous modules. + context.completeLoad(moduleName); + + //Bind the value of that module to the value for this + //resource ID. + localRequire([moduleName], load); + }); + + //Use parentName here since the plugin's name is not reliable, + //could be some weird string with no path that actually wants to + //reference the parentName's path. + plugin.load(map.name, localRequire, load, config); + })); + + context.enable(pluginMap, this); + this.pluginMaps[pluginMap.id] = pluginMap; + }, + + enable: function () { + enabledRegistry[this.map.id] = this; + this.enabled = true; + + //Set flag mentioning that the module is enabling, + //so that immediate calls to the defined callbacks + //for dependencies do not trigger inadvertent load + //with the depCount still being zero. + this.enabling = true; + + //Enable each dependency + each(this.depMaps, bind(this, function (depMap, i) { + var id, mod, handler; + + if (typeof depMap === 'string') { + //Dependency needs to be converted to a depMap + //and wired up to this module. + depMap = makeModuleMap(depMap, + (this.map.isDefine ? this.map : this.map.parentMap), + false, + !this.skipMap); + this.depMaps[i] = depMap; + + handler = getOwn(handlers, depMap.id); + + if (handler) { + this.depExports[i] = handler(this); + return; + } + + this.depCount += 1; + + on(depMap, 'defined', bind(this, function (depExports) { + this.defineDep(i, depExports); + this.check(); + })); + + if (this.errback) { + on(depMap, 'error', this.errback); + } + } + + id = depMap.id; + mod = registry[id]; + + //Skip special modules like 'require', 'exports', 'module' + //Also, don't call enable if it is already enabled, + //important in circular dependency cases. + if (!hasProp(handlers, id) && mod && !mod.enabled) { + context.enable(depMap, this); + } + })); + + //Enable each plugin that is used in + //a dependency + eachProp(this.pluginMaps, bind(this, function (pluginMap) { + var mod = getOwn(registry, pluginMap.id); + if (mod && !mod.enabled) { + context.enable(pluginMap, this); + } + })); + + this.enabling = false; + + this.check(); + }, + + on: function (name, cb) { + var cbs = this.events[name]; + if (!cbs) { + cbs = this.events[name] = []; + } + cbs.push(cb); + }, + + emit: function (name, evt) { + each(this.events[name], function (cb) { + cb(evt); + }); + if (name === 'error') { + //Now that the error handler was triggered, remove + //the listeners, since this broken Module instance + //can stay around for a while in the registry. + delete this.events[name]; + } + } + }; + + function callGetModule(args) { + //Skip modules already defined. + if (!hasProp(defined, args[0])) { + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); + } + } + + function removeListener(node, func, name, ieName) { + //Favor detachEvent because of IE9 + //issue, see attachEvent/addEventListener comment elsewhere + //in this file. + if (node.detachEvent && !isOpera) { + //Probably IE. If not it will throw an error, which will be + //useful to know. + if (ieName) { + node.detachEvent(ieName, func); + } + } else { + node.removeEventListener(name, func, false); + } + } + + /** + * Given an event from a script node, get the requirejs info from it, + * and then removes the event listeners on the node. + * @param {Event} evt + * @returns {Object} + */ + function getScriptData(evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + var node = evt.currentTarget || evt.srcElement; + + //Remove the listeners once here. + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); + removeListener(node, context.onScriptError, 'error'); + + return { + node: node, + id: node && node.getAttribute('data-requiremodule') + }; + } + + function intakeDefines() { + var args; + + //Any defined modules in the global queue, intake them now. + takeGlobalQueue(); + + //Make sure any remaining defQueue items get properly processed. + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); + } else { + //args are id, deps, factory. Should be normalized by the + //define() function. + callGetModule(args); + } + } + } + + context = { + config: config, + contextName: contextName, + registry: registry, + defined: defined, + urlFetched: urlFetched, + defQueue: defQueue, + Module: Module, + makeModuleMap: makeModuleMap, + nextTick: req.nextTick, + onError: onError, + + /** + * Set a configuration for the context. + * @param {Object} cfg config object to integrate. + */ + configure: function (cfg) { + //Make sure the baseUrl ends in a slash. + if (cfg.baseUrl) { + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { + cfg.baseUrl += '/'; + } + } + + //Save off the paths and packages since they require special processing, + //they are additive. + var pkgs = config.pkgs, + shim = config.shim, + objs = { + paths: true, + config: true, + map: true + }; + + eachProp(cfg, function (value, prop) { + if (objs[prop]) { + if (prop === 'map') { + if (!config.map) { + config.map = {}; + } + mixin(config[prop], value, true, true); + } else { + mixin(config[prop], value, true); + } + } else { + config[prop] = value; + } + }); + + //Merge shim + if (cfg.shim) { + eachProp(cfg.shim, function (value, id) { + //Normalize the structure + if (isArray(value)) { + value = { + deps: value + }; + } + if ((value.exports || value.init) && !value.exportsFn) { + value.exportsFn = context.makeShimExports(value); + } + shim[id] = value; + }); + config.shim = shim; + } + + //Adjust packages if necessary. + if (cfg.packages) { + each(cfg.packages, function (pkgObj) { + var location; + + pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; + location = pkgObj.location; + + //Create a brand new object on pkgs, since currentPackages can + //be passed in again, and config.pkgs is the internal transformed + //state for all package configs. + pkgs[pkgObj.name] = { + name: pkgObj.name, + location: location || pkgObj.name, + //Remove leading dot in main, so main paths are normalized, + //and remove any trailing .js, since different package + //envs have different conventions: some use a module name, + //some use a file name. + main: (pkgObj.main || 'main') + .replace(currDirRegExp, '') + .replace(jsSuffixRegExp, '') + }; + }); + + //Done with modifications, assing packages back to context config + config.pkgs = pkgs; + } + + //If there are any "waiting to execute" modules in the registry, + //update the maps for them, since their info, like URLs to load, + //may have changed. + eachProp(registry, function (mod, id) { + //If module already has init called, since it is too + //late to modify them, and ignore unnormalized ones + //since they are transient. + if (!mod.inited && !mod.map.unnormalized) { + mod.map = makeModuleMap(id); + } + }); + + //If a deps array or a config callback is specified, then call + //require with those args. This is useful when require is defined as a + //config object before require.js is loaded. + if (cfg.deps || cfg.callback) { + context.require(cfg.deps || [], cfg.callback); + } + }, + + makeShimExports: function (value) { + function fn() { + var ret; + if (value.init) { + ret = value.init.apply(global, arguments); + } + return ret || (value.exports && getGlobal(value.exports)); + } + return fn; + }, + + makeRequire: function (relMap, options) { + options = options || {}; + + function localRequire(deps, callback, errback) { + var id, map, requireMod; + + if (options.enableBuildCallback && callback && isFunction(callback)) { + callback.__requireJsBuild = true; + } + + if (typeof deps === 'string') { + if (isFunction(callback)) { + //Invalid call + return onError(makeError('requireargs', 'Invalid require call'), errback); + } + + //If require|exports|module are requested, get the + //value for them from the special handlers. Caveat: + //this only works while module is being defined. + if (relMap && hasProp(handlers, deps)) { + return handlers[deps](registry[relMap.id]); + } + + //Synchronous access to one module. If require.get is + //available (as in the Node adapter), prefer that. + if (req.get) { + return req.get(context, deps, relMap, localRequire); + } + + //Normalize module name, if it contains . or .. + map = makeModuleMap(deps, relMap, false, true); + id = map.id; + + if (!hasProp(defined, id)) { + return onError(makeError('notloaded', 'Module name "' + + id + + '" has not been loaded yet for context: ' + + contextName + + (relMap ? '' : '. Use require([])'))); + } + return defined[id]; + } + + //Grab defines waiting in the global queue. + intakeDefines(); + + //Mark all the dependencies as needing to be loaded. + context.nextTick(function () { + //Some defines could have been added since the + //require call, collect them. + intakeDefines(); + + requireMod = getModule(makeModuleMap(null, relMap)); + + //Store if map config should be applied to this require + //call for dependencies. + requireMod.skipMap = options.skipMap; + + requireMod.init(deps, callback, errback, { + enabled: true + }); + + checkLoaded(); + }); + + return localRequire; + } + + mixin(localRequire, { + isBrowser: isBrowser, + + /** + * Converts a module name + .extension into an URL path. + * *Requires* the use of a module name. It does not support using + * plain URLs like nameToUrl. + */ + toUrl: function (moduleNamePlusExt) { + var ext, + index = moduleNamePlusExt.lastIndexOf('.'), + segment = moduleNamePlusExt.split('/')[0], + isRelative = segment === '.' || segment === '..'; + + //Have a file extension alias, and it is not the + //dots from a relative path. + if (index !== -1 && (!isRelative || index > 1)) { + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); + } + + return context.nameToUrl(normalize(moduleNamePlusExt, + relMap && relMap.id, true), ext, true); + }, + + defined: function (id) { + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); + }, + + specified: function (id) { + id = makeModuleMap(id, relMap, false, true).id; + return hasProp(defined, id) || hasProp(registry, id); + } + }); + + //Only allow undef on top level require calls + if (!relMap) { + localRequire.undef = function (id) { + //Bind any waiting define() calls to this context, + //fix for #408 + takeGlobalQueue(); + + var map = makeModuleMap(id, relMap, true), + mod = getOwn(registry, id); + + delete defined[id]; + delete urlFetched[map.url]; + delete undefEvents[id]; + + if (mod) { + //Hold on to listeners in case the + //module will be attempted to be reloaded + //using a different config. + if (mod.events.defined) { + undefEvents[id] = mod.events; + } + + cleanRegistry(id); + } + }; + } + + return localRequire; + }, + + /** + * Called to enable a module if it is still in the registry + * awaiting enablement. A second arg, parent, the parent module, + * is passed in for context, when this method is overriden by + * the optimizer. Not shown here to keep code compact. + */ + enable: function (depMap) { + var mod = getOwn(registry, depMap.id); + if (mod) { + getModule(depMap).enable(); + } + }, + + /** + * Internal method used by environment adapters to complete a load event. + * A load event could be a script load or just a load pass from a synchronous + * load call. + * @param {String} moduleName the name of the module to potentially complete. + */ + completeLoad: function (moduleName) { + var found, args, mod, + shim = getOwn(config.shim, moduleName) || {}, + shExports = shim.exports; + + takeGlobalQueue(); + + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + args[0] = moduleName; + //If already found an anonymous module and bound it + //to this name, then this is some other anon module + //waiting for its completeLoad to fire. + if (found) { + break; + } + found = true; + } else if (args[0] === moduleName) { + //Found matching define call for this script! + found = true; + } + + callGetModule(args); + } + + //Do this after the cycle of callGetModule in case the result + //of those calls/init calls changes the registry. + mod = getOwn(registry, moduleName); + + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { + if (hasPathFallback(moduleName)) { + return; + } else { + return onError(makeError('nodefine', + 'No define call for ' + moduleName, + null, + [moduleName])); + } + } else { + //A script that does not call define(), so just simulate + //the call for it. + callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); + } + } + + checkLoaded(); + }, + + /** + * Converts a module name to a file path. Supports cases where + * moduleName may actually be just an URL. + * Note that it **does not** call normalize on the moduleName, + * it is assumed to have already been normalized. This is an + * internal API, not a public one. Use toUrl for the public API. + */ + nameToUrl: function (moduleName, ext, skipExt) { + var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, + parentPath; + + //If a colon is in the URL, it indicates a protocol is used and it is just + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) + //or ends with .js, then assume the user meant to use an url and not a module id. + //The slash is important for protocol-less URLs as well as full paths. + if (req.jsExtRegExp.test(moduleName)) { + //Just a plain path, not module name lookup, so just return it. + //Add extension if it is included. This is a bit wonky, only non-.js things pass + //an extension, this method probably needs to be reworked. + url = moduleName + (ext || ''); + } else { + //A module that needs to be converted to a path. + paths = config.paths; + pkgs = config.pkgs; + + syms = moduleName.split('/'); + //For each module name segment, see if there is a path + //registered for it. Start with most specific name + //and work up from it. + for (i = syms.length; i > 0; i -= 1) { + parentModule = syms.slice(0, i).join('/'); + pkg = getOwn(pkgs, parentModule); + parentPath = getOwn(paths, parentModule); + if (parentPath) { + //If an array, it means there are a few choices, + //Choose the one that is desired + if (isArray(parentPath)) { + parentPath = parentPath[0]; + } + syms.splice(0, i, parentPath); + break; + } else if (pkg) { + //If module name is just the package name, then looking + //for the main module. + if (moduleName === pkg.name) { + pkgPath = pkg.location + '/' + pkg.main; + } else { + pkgPath = pkg.location; + } + syms.splice(0, i, pkgPath); + break; + } + } + + //Join the path parts together, then figure out if baseUrl is needed. + url = syms.join('/'); + url += (ext || (/\?/.test(url) || skipExt ? '' : '.js')); + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; + } + + return config.urlArgs ? url + + ((url.indexOf('?') === -1 ? '?' : '&') + + config.urlArgs) : url; + }, + + //Delegates to req.load. Broken out as a separate function to + //allow overriding in the optimizer. + load: function (id, url) { + req.load(context, id, url); + }, + + /** + * Executes a module callack function. Broken out as a separate function + * solely to allow the build system to sequence the files in the built + * layer in the right sequence. + * + * @private + */ + execCb: function (name, callback, args, exports) { + return callback.apply(exports, args); + }, + + /** + * callback for script loads, used to check status of loading. + * + * @param {Event} evt the event from the browser for the script + * that was loaded. + */ + onScriptLoad: function (evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + if (evt.type === 'load' || + (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { + //Reset interactive script so a script node is not held onto for + //to long. + interactiveScript = null; + + //Pull out the name of the module and the context. + var data = getScriptData(evt); + context.completeLoad(data.id); + } + }, + + /** + * Callback for script errors. + */ + onScriptError: function (evt) { + var data = getScriptData(evt); + if (!hasPathFallback(data.id)) { + return onError(makeError('scripterror', 'Script error', evt, [data.id])); + } + } + }; + + context.require = context.makeRequire(); + return context; + } + + /** + * Main entry point. + * + * If the only argument to require is a string, then the module that + * is represented by that string is fetched for the appropriate context. + * + * If the first argument is an array, then it will be treated as an array + * of dependency string names to fetch. An optional function callback can + * be specified to execute when all of those dependencies are available. + * + * Make a local req variable to help Caja compliance (it assumes things + * on a require that are not standardized), and to give a short + * name for minification/local scope use. + */ + req = requirejs = function (deps, callback, errback, optional) { + + //Find the right context, use default + var context, config, + contextName = defContextName; + + // Determine if have config object in the call. + if (!isArray(deps) && typeof deps !== 'string') { + // deps is a config object + config = deps; + if (isArray(callback)) { + // Adjust args if there are dependencies + deps = callback; + callback = errback; + errback = optional; + } else { + deps = []; + } + } + + if (config && config.context) { + contextName = config.context; + } + + context = getOwn(contexts, contextName); + if (!context) { + context = contexts[contextName] = req.s.newContext(contextName); + } + + if (config) { + context.configure(config); + } + + return context.require(deps, callback, errback); + }; + + /** + * Support require.config() to make it easier to cooperate with other + * AMD loaders on globally agreed names. + */ + req.config = function (config) { + return req(config); + }; + + /** + * Execute something after the current tick + * of the event loop. Override for other envs + * that have a better solution than setTimeout. + * @param {Function} fn function to execute later. + */ + req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { + setTimeout(fn, 4); + } : function (fn) { fn(); }; + + /** + * Export require as a global, but only if it does not already exist. + */ + if (!require) { + require = req; + } + + req.version = version; + + //Used to filter out dependencies that are already paths. + req.jsExtRegExp = /^\/|:|\?|\.js$/; + req.isBrowser = isBrowser; + s = req.s = { + contexts: contexts, + newContext: newContext + }; + + //Create default context. + req({}); + + //Exports some context-sensitive methods on global require. + each([ + 'toUrl', + 'undef', + 'defined', + 'specified' + ], function (prop) { + //Reference from contexts instead of early binding to default context, + //so that during builds, the latest instance of the default context + //with its config gets used. + req[prop] = function () { + var ctx = contexts[defContextName]; + return ctx.require[prop].apply(ctx, arguments); + }; + }); + + if (isBrowser) { + head = s.head = document.getElementsByTagName('head')[0]; + //If BASE tag is in play, using appendChild is a problem for IE6. + //When that browser dies, this can be removed. Details in this jQuery bug: + //http://dev.jquery.com/ticket/2709 + baseElement = document.getElementsByTagName('base')[0]; + if (baseElement) { + head = s.head = baseElement.parentNode; + } + } + + /** + * Any errors that require explicitly generates will be passed to this + * function. Intercept/override it if you want custom error handling. + * @param {Error} err the error object. + */ + req.onError = function (err) { + throw err; + }; + + /** + * Does the request to load a module for the browser case. + * Make this a separate function to allow other environments + * to override it. + * + * @param {Object} context the require context to find state. + * @param {String} moduleName the name of the module. + * @param {Object} url the URL to the module. + */ + req.load = function (context, moduleName, url) { + var config = (context && context.config) || {}, + node; + if (isBrowser) { + //In the browser so use a script tag + node = config.xhtml ? + document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : + document.createElement('script'); + node.type = config.scriptType || 'text/javascript'; + node.charset = 'utf-8'; + node.async = true; + + node.setAttribute('data-requirecontext', context.contextName); + node.setAttribute('data-requiremodule', moduleName); + + //Set up load listener. Test attachEvent first because IE9 has + //a subtle issue in its addEventListener and script onload firings + //that do not match the behavior of all other browsers with + //addEventListener support, which fire the onload event for a + //script right after the script execution. See: + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution + //UNFORTUNATELY Opera implements attachEvent but does not follow the script + //script execution mode. + if (node.attachEvent && + //Check if node.attachEvent is artificially added by custom script or + //natively supported by browser + //read https://github.com/jrburke/requirejs/issues/187 + //if we can NOT find [native code] then it must NOT natively supported. + //in IE8, node.attachEvent does not have toString() + //Note the test for "[native code" with no closing brace, see: + //https://github.com/jrburke/requirejs/issues/273 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && + !isOpera) { + //Probably IE. IE (at least 6-8) do not fire + //script onload right after executing the script, so + //we cannot tie the anonymous define call to a name. + //However, IE reports the script as being in 'interactive' + //readyState at the time of the define call. + useInteractive = true; + + node.attachEvent('onreadystatechange', context.onScriptLoad); + //It would be great to add an error handler here to catch + //404s in IE9+. However, onreadystatechange will fire before + //the error handler, so that does not help. If addEventListener + //is used, then IE will fire error before load, but we cannot + //use that pathway given the connect.microsoft.com issue + //mentioned above about not doing the 'script execute, + //then fire the script load event listener before execute + //next script' that other browsers do. + //Best hope: IE10 fixes the issues, + //and then destroys all installs of IE 6-9. + //node.attachEvent('onerror', context.onScriptError); + } else { + node.addEventListener('load', context.onScriptLoad, false); + node.addEventListener('error', context.onScriptError, false); + } + node.src = url; + + //For some cache cases in IE 6-8, the script executes before the end + //of the appendChild execution, so to tie an anonymous define + //call to the module name (which is stored on the node), hold on + //to a reference to this node, but clear after the DOM insertion. + currentlyAddingScript = node; + if (baseElement) { + head.insertBefore(node, baseElement); + } else { + head.appendChild(node); + } + currentlyAddingScript = null; + + return node; + } else if (isWebWorker) { + try { + //In a web worker, use importScripts. This is not a very + //efficient use of importScripts, importScripts will block until + //its script is downloaded and evaluated. However, if web workers + //are in play, the expectation that a build has been done so that + //only one script needs to be loaded anyway. This may need to be + //reevaluated if other use cases become common. + importScripts(url); + + //Account for anonymous modules + context.completeLoad(moduleName); + } catch (e) { + context.onError(makeError('importscripts', + 'importScripts failed for ' + + moduleName + ' at ' + url, + e, + [moduleName])); + } + } + }; + + function getInteractiveScript() { + if (interactiveScript && interactiveScript.readyState === 'interactive') { + return interactiveScript; + } + + eachReverse(scripts(), function (script) { + if (script.readyState === 'interactive') { + return (interactiveScript = script); + } + }); + return interactiveScript; + } + + //Look for a data-main script attribute, which could also adjust the baseUrl. + if (isBrowser) { + //Figure out baseUrl. Get it from the script tag with require.js in it. + eachReverse(scripts(), function (script) { + //Set the 'head' where we can append children by + //using the script's parent. + if (!head) { + head = script.parentNode; + } + + //Look for a data-main attribute to set main script for the page + //to load. If it is there, the path to data main becomes the + //baseUrl, if it is not already set. + dataMain = script.getAttribute('data-main'); + if (dataMain) { + //Set final baseUrl if there is not already an explicit one. + if (!cfg.baseUrl) { + //Pull off the directory of data-main for use as the + //baseUrl. + src = dataMain.split('/'); + mainScript = src.pop(); + subPath = src.length ? src.join('/') + '/' : './'; + + cfg.baseUrl = subPath; + dataMain = mainScript; + } + + //Strip off any trailing .js since dataMain is now + //like a module name. + dataMain = dataMain.replace(jsSuffixRegExp, ''); + + //Put the data-main script in the files to load. + cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain]; + + return true; + } + }); + } + + /** + * The function that handles definitions of modules. Differs from + * require() in that a string for the module should be the first argument, + * and the function to execute after dependencies are loaded should + * return a value to define the module corresponding to the first argument's + * name. + */ + define = function (name, deps, callback) { + var node, context; + + //Allow for anonymous modules + if (typeof name !== 'string') { + //Adjust args appropriately + callback = deps; + deps = name; + name = null; + } + + //This module may not have dependencies + if (!isArray(deps)) { + callback = deps; + deps = []; + } + + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!deps.length && isFunction(callback)) { + //Remove comments from the callback string, + //look for require calls, and pull them into the dependencies, + //but only if there are function args. + if (callback.length) { + callback + .toString() + .replace(commentRegExp, '') + .replace(cjsRequireRegExp, function (match, dep) { + deps.push(dep); + }); + + //May be a CommonJS thing even without require calls, but still + //could use exports, and module. Avoid doing exports and module + //work though if it just needs require. + //REQUIRES the function to expect the CommonJS variables in the + //order listed below. + deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); + } + } + + //If in IE 6-8 and hit an anonymous define() call, do the interactive + //work. + if (useInteractive) { + node = currentlyAddingScript || getInteractiveScript(); + if (node) { + if (!name) { + name = node.getAttribute('data-requiremodule'); + } + context = contexts[node.getAttribute('data-requirecontext')]; + } + } + + //Always save off evaluating the def call until the script onload handler. + //This allows multiple modules to be in a file without prematurely + //tracing dependencies, and allows for anonymous module support, + //where the module name is not known until the script onload event + //occurs. If no context, use the global queue, and get it processed + //in the onscript load callback. + (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); + }; + + define.amd = { + jQuery: true + }; + + + /** + * Executes the text. Normally just uses eval, but can be modified + * to use a better, environment-specific call. Only used for transpiling + * loader plugins, not for plain JS modules. + * @param {String} text the text to execute/evaluate. + */ + req.exec = function (text) { + /*jslint evil: true */ + return eval(text); + }; + + //Set up with config info. + req(cfg); +}(this)); diff --git a/demos/snap-ad/src/js/vendor/require.min.js b/demos/snap-ad/src/js/vendor/require.min.js new file mode 100644 index 0000000..84d1d67 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/require.min.js @@ -0,0 +1,36 @@ +/* + RequireJS 2.1.10 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. + Available via the MIT or new BSD license. + see: http://github.com/jrburke/requirejs for details +*/ +var requirejs,require,define; +(function(ca){function G(b){return"[object Function]"===N.call(b)}function H(b){return"[object Array]"===N.call(b)}function v(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&& +(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a= +this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f); +if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval", +"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(K,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b, +a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(K,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m, +nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b, +a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild= +!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(K,f))return K[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}M();i.nextTick(function(){M();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!== +d&&(!("."===g||".."===g)||1g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)): +(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,M=g,D?y.insertBefore(g,D):y.appendChild(g),M=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(L=b.getAttribute("data-main"))return q=L,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl= +Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=L),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=M))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b|| +(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this); diff --git a/demos/snap-ad/src/js/vendor/snap.svg-min.js b/demos/snap-ad/src/js/vendor/snap.svg-min.js new file mode 100755 index 0000000..cfc6ef1 --- /dev/null +++ b/demos/snap-ad/src/js/vendor/snap.svg-min.js @@ -0,0 +1,20 @@ +// Snap.svg 0.2.0 +// +// 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. +// +// build: 2014-01-23 +!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],b("mina.stop."+a.id,a)},n=function(){var a=this;a.pdif||(delete c[a.id],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=0;for(var f in c)if(c.hasOwnProperty(f)){var g,h=c[f],i=h.get();if(a++,h.s=(i-h.b)/(h.dur/h.spd),h.s>=1&&(delete c[f],h.s=1,a--,function(a){setTimeout(function(){b("mina.finish."+a.id,a)})}(h)),e(h.start)){g=[];for(var j=0,k=h.start.length;k>j;j++)g[j]=+h.start[j]+(h.end[j]-h.start[j])*h.easing(h.s)}else g=+h.start+(h.end-h.start)*h.easing(h.s);h.set(g)}a&&d(p)},q=function(a,b,e,f,g,i,r){var s={id:h(),start:a,end:b,b:e,s:0,dur:f-e,spd:1,get:g,set:i,easing:r||q.linear,status:j,speed:k,duration:l,stop:m,pause:n,resume:o};c[s.id]=s;var t,u=0;for(t in c)if(c.hasOwnProperty(t)&&(u++,2==u))break;return 1==u&&d(p),s};return q.time=i,q.getById=function(a){return c[a]||null},q.linear=function(a){return a},q.easeout=function(a){return Math.pow(a,1.7)},q.easein=function(a){return Math.pow(a,.48)},q.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},q.backin=function(a){if(1==a)return 1;var b=1.70158;return a*a*((b+1)*a-b)},q.backout=function(a){if(0==a)return 0;a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},q.elastic=function(a){return a==!!a?a:Math.pow(2,-10*a)*Math.sin(2*(a-.075)*Math.PI/.3)+1},q.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=q,q}("undefined"==typeof b?function(){}:b),d=function(){function d(a,b){if(a){if(a.tagName)return z(a);if(a instanceof u)return a;if(null==b)return a=I.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("string"==typeof a&&(a=e(a)),"string"==typeof b)return"xlink:"==b.substring(0,6)?a.getAttributeNS(fb,b.substring(6)):"xml:"==b.substring(0,4)?a.getAttributeNS(gb,b.substring(4)):a.getAttribute(b);for(var c in b)if(b[J](c)){var d=K(b[c]);d?"xlink:"==c.substring(0,6)?a.setAttributeNS(fb,c.substring(6),d):"xml:"==c.substring(0,4)?a.setAttributeNS(gb,c.substring(4),d):a.setAttribute(c,d):a.removeAttribute(c)}}else a=I.doc.createElementNS(gb,a);return a}function f(a,b){return b=K.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)||U.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[J](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[J](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*N.atan2(-h,-g)/R+360)%360:0}return k(a,b,e,f)-k(c,d,e,f)}function l(a){return a%360*R/180}function m(a){return 180*a/R%360}function n(a,b,c,d,e,f){return null==b&&"[object SVGMatrix]"==U.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=+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))}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&&(2==d.length&&d.push(0,0),1==d.length&&d.push(d[0],0,0)),b.push("skewX"==c?["m",1,0,N.tan(l(d[0])),1,0,0]:"skewY"==c?["m",1,N.tan(l(d[0])),0,1,0,0]:[c.charAt(0)].concat(d)),a}),b}function p(a,b){var c=qb(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=K(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=a.node.getAttribute("linearGradient"==a.type||"radialGradient"==a.type?"gradientTransform":"pattern"==a.type?"patternTransform":"transform"),!b)return new n;b=o(b)}else b=d._.rgTransform.test(b)?K(b).replace(/\.{3}|…/g,a._.transform||S):o(b),f(b,"array")&&(b=d.path?d.path.toString.call(b):K(b)),a._.transform=b;var e=p(b,a.getBBox(1));return c?e:void(a.matrix=e)}function r(a){var b=d._.someDefs;if(b&&rb(b.ownerDocument.documentElement,b))return b;var c=a.node.ownerSVGElement&&z(a.node.ownerSVGElement)||a.node.parentNode&&z(a.node.parentNode)||d.select("svg")||d(0,0),e=c.select("defs"),f=null==e?!1:e.node;return f||(f=x("defs",c.node).node),d._.someDefs=f,f}function s(a,b,c){function d(a){return null==a?S:a==+a?a:(e(j,{width:a}),j.getBBox().width)}function f(a){return null==a?S:a==+a?a:(e(j,{height:a}),j.getBBox().height)}function g(d,e){null==b?i[d]=e(a.attr(d)):d==b&&(i=e(null==c?a.attr(d):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.type=a,d}function y(a,b){var c,d,f,g=y.prototype;if(a&&"svg"==a.tagName){if(a.snap in hb)return hb[a.snap];c=new u(a),d=a.getElementsByTagName("desc")[0],f=a.getElementsByTagName("defs")[0],d||(d=e("desc"),d.appendChild(I.doc.createTextNode("Created with Snap")),c.node.appendChild(d)),f||(f=e("defs"),c.node.appendChild(f)),c.defs=f;for(var h in g)g[J](h)&&(c[h]=g[h]);c.paper=c.root=c}else c=x("svg",I.doc.body),e(c.node,{height:b,version:1.1,width:a,xmlns:gb});return c}function z(a){return a?a instanceof u||a instanceof w?a:"svg"==a.tagName?new y(a):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,N.abs(b-a),N.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=ib(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=ib(g.node.id)):f=c}else f=K(f);var h={};h[a]=f,e(this.node,h),this.node.style[a]=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}d.version="0.2.0",d.toString=function(){return"Snap v"+this.version},d._={};var I={win:a,doc:a.document};d._.glob=I;var J="hasOwnProperty",K=String,L=parseFloat,M=parseInt,N=Math,O=N.max,P=N.min,Q=N.abs,R=(N.pow,N.PI),S=(N.round,""),T=" ",U=Object.prototype.toString,V=/^\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|°|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|°|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,W=/^url\(#?([^)]+)\)$/,X=" \n \f\r   ᠎              \u2028\u2029",Y=new RegExp("[,"+X+"]+"),Z=(new RegExp("["+X+"]","g"),new RegExp("["+X+"]*,["+X+"]*")),$={hs:1,rg:1},_=new RegExp("([a-z])["+X+",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?["+X+"]*,?["+X+"]*)+)","ig"),ab=new RegExp("([rstm])["+X+",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?["+X+"]*,?["+X+"]*)+)","ig"),bb=new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)["+X+"]*,?["+X+"]*","ig"),cb=0,db="S"+(+new Date).toString(36),eb=function(){return db+(cb++).toString(36)},fb="http://www.w3.org/1999/xlink",gb="http://www.w3.org/2000/svg",hb={},ib=d.url=function(a){return"url('#"+a+"')"};d._.$=e,d._.id=eb,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 K(b).replace(a,function(a,b){return c(a,b,d)})}}();var jb=function(){function a(){this.parentNode.removeChild(this)}return function(b,c){var d=I.doc.createElement("img"),e=I.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(Q(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=N.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=+N.cos(a).toFixed(9),e=+N.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[K.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.split=function(){var a={};a.dx=this.e,a.dy=this.f;var d=[[this.a,this.c],[this.b,this.d]];a.scalex=N.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=N.sqrt(b(d[1])),c(d[1]),a.shear/=a.scaley;var e=-d[0][1],f=d[1][1];return 0>f?(a.rotate=m(N.acos(f)),0>e&&(a.rotate=360-a.rotate)):a.rotate=m(N.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.isSimple?(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)]:S)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:S)+(b.rotate?"r"+[+b.rotate.toFixed(4),0,0]:S)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(n.prototype),d.Matrix=n,d.getRGB=j(function(a){if(!a||(a=K(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:nb};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:nb};if(!($[J](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=kb(a)),!a)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:nb};var b,c,e,g,h,i,j=a.match(V);return j?(j[2]&&(e=M(j[2].substring(5),16),c=M(j[2].substring(3,5),16),b=M(j[2].substring(1,3),16)),j[3]&&(e=M((h=j[3].charAt(3))+h,16),c=M((h=j[3].charAt(2))+h,16),b=M((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4].split(Z),b=L(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),c=L(i[1]),"%"==i[1].slice(-1)&&(c*=2.55),e=L(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=L(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5].split(Z),b=L(i[0]),"%"==i[0].slice(-1)&&(b/=100),c=L(i[1]),"%"==i[1].slice(-1)&&(c/=100),e=L(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=L(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),d.hsb2rgb(b,c,e,g)):j[6]?(i=j[6].split(Z),b=L(i[0]),"%"==i[0].slice(-1)&&(b/=100),c=L(i[1]),"%"==i[1].slice(-1)&&(c/=100),e=L(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=L(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),d.hsl2rgb(b,c,e,g)):(b=P(N.round(b),255),c=P(N.round(c),255),e=P(N.round(e),255),g=P(O(g,0),1),j={r:b,g:c,b:e,toString:nb},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:nb}},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=N.round;return"rgba("+[e(a),e(b),e(c),+d.toFixed(2)]+")"}return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)});var kb=function(a){var b=I.doc.getElementsByTagName("head")[0],c="rgb(255, 0, 0)";return(kb=j(function(a){if("red"==a.toLowerCase())return c;b.style.color=c,b.style.color=a;var d=I.doc.defaultView.getComputedStyle(b,S).getPropertyValue("color");return d==c?null:d}))(a)},lb=function(){return"hsb("+[this.h,this.s,this.b]+")"},mb=function(){return"hsl("+[this.h,this.s,this.l]+")"},nb=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},ob=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]},pb=function(a,b,c,e){a=N.round(255*a),b=N.round(255*b),c=N.round(255*c);var g={r:a,g:b,b:c,opacity:f(e,"finite")?e:1,hex:d.rgb(a,b,c),toString:nb};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=nb,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-Q(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],pb(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-Q(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],pb(e,g,h,d)},d.rgb2hsb=function(a,b,c){c=ob(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=O(a,b,c),g=f-P(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:lb}},d.rgb2hsl=function(a,b,c){c=ob(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=O(a,b,c),h=P(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:mb}},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||K(a).replace(_,function(a,b,d){var f=[],g=b.toLowerCase();if(d.replace(bb,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 qb=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||K(a).replace(ab,function(a,c,d){{var e=[];c.toLowerCase()}d.replace(bb,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]["+X+"]*-?\\.?\\d","i"),d._.transform2matrix=p,d._unit2px=s;var rb=I.doc.contains||I.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(I.doc.querySelector(a))},d.selectAll=function(a){for(var b=I.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;d.node}if(!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[J](g)&&b("snap.util.attr."+g,d,a[g]);return d},a.getBBox=function(a){var b=this;if("use"==b.type&&(b=b.original),b.removed)return{};var c=b._;return a?(c.bboxwt=d.path.get[b.type]?d.path.getBBox(b.realPath=d.path.get[b.type](b)):d._.box(b.node.getBBox()),d._.box(c.bboxwt)):(b.realPath=(d.path.get[b.type]||d.path.get.deflt)(b),c.bbox=d.path.getBBox(d.path.map(b.realPath,b.matrix)),d._.box(c.bbox))};var j=function(){return this.string};a.transform=function(a){var b=this._;if(null==a){var c=new n(this.node.getCTM()),d=q(this),f=d.toTransformString(),g=K(d)==K(this.matrix)?b.transform:f;return{string:g,globalMatrix:c,localMatrix:d,diffMatrix:c.clone().add(d.invert()),global:c.toTransformString(),local:f,toString:j}}return a instanceof n&&(a=a.toTransformString()),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 k&&(g=a.callback,e=a.easing,d=e.dur,a=a.attr);var i,j,l,m,n=[],o=[],p={},q=this;for(var r in a)if(a[J](r)){q.equal?(m=q.equal(r,K(a[r])),i=m.from,j=m.to,l=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,l),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[J](c)&&(b[c]=p[c](a));q.attr(b)},e);return q.anims[u.id]=u,u._attrs=a,u._callback=g,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 l={};a.data=function(a,c){var e=l[this.id]=l[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[J](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?l[this.id]={}:l[this.id]&&delete l[this.id][a],this},a.outerSVG=a.toString=i(1),a.innerSVG=i()}(u.prototype),d.parse=function(a){var b=I.doc.createDocumentFragment(),c=!0,d=I.doc.createElement("div");if(a=K(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=S,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=I.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")&&"x"in 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")&&"cx"in 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):jb(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")&&"cx"in 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(b){var c=x("g",this.node);c.add=t;for(var d in a)a[J](d)&&(c[d]=a[d]);return 1==arguments.length&&b&&!b.type?c.attr(b):arguments.length&&c.add(Array.prototype.slice.call(arguments,0)),c},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=I.doc.createDocumentFragment(),c=I.doc.createElement("div"),d=this.node.cloneNode(!0);return b.appendChild(c),c.appendChild(d),e(d,{xmlns:gb}),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=eb();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:ib(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":ib(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=K(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=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=K(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=K(a);for(var c=I.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.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(),void delete this.textPath}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=S(j,3),l=S(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*O.atan2(q-s,r-t)/P;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=E.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]*O.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(!(R(a,c)R(e,g)||R(b,d)R(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<+Q(a,c).toFixed(2)||n>+R(a,c).toFixed(2)||n<+Q(e,g).toFixed(2)||n>+R(e,g).toFixed(2)||o<+Q(b,d).toFixed(2)||o>+R(b,d).toFixed(2)||o<+Q(f,h).toFixed(2)||o>+R(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=T(w.x-v.x)<.001?"y":"x",A=T(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+T((B[z]-v[z])/(w[z]-v[z]))*(w.t-v.t),D=x.t+T((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=F(a),b=F(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 K(b.bbox);if(!a)return d();a=F(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=E(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=Q.apply(0,h),n=Q.apply(0,i),o=R.apply(0,h),p=R.apply(0,i),q=d(m,n,o-m,p-n);return b.bbox=K(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),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(J(b,"array")&&J(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(H(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(H(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*P/180,n=P/180*(+f||0),o=[],p=a._.cacher(function(a,b,c){var d=a*O.cos(c)-b*O.sin(c),e=a*O.sin(c)+b*O.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=(O.cos(P/180*f),O.sin(P/180*f),(b-i)/2),r=(c-j)/2,s=q*q/(d*d)+r*r/(e*e);s>1&&(s=O.sqrt(s),d=s*d,e=s*e);var t=d*d,u=e*e,v=(g==h?-1:1)*O.sqrt(T((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=O.asin(((c-x)/e).toFixed(9)),z=O.asin(((j-x)/e).toFixed(9));y=w>b?P-y:y,z=w>i?P-z:z,0>y&&(y=2*P+y),0>z&&(z=2*P+z),h&&y>z&&(y-=2*P),!h&&z>y&&(z-=2*P)}var A=z-y;if(T(A)>m){var B=z,D=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+d*O.cos(z),j=x+e*O.sin(z),o=C(i,j,d,e,f,0,h,D,E,[z,B,w,x])}A=z-y;var F=O.cos(y),G=O.sin(y),H=O.cos(z),I=O.sin(z),J=O.tan(A/4),K=4/3*d*J,L=4/3*e*J,M=[b,c],N=[b+K*G,c-L*F],Q=[i+K*I,j-L*H],R=[i,j];if(N[0]=2*M[0]-N[0],N[1]=2*M[1]-N[1],k)return[N,Q,R].concat(o);o=[N,Q,R].concat(o).join().split(",");for(var S=[],U=0,V=o.length;V>U;U++)S[U]=U%2?p(o[U-1],o[U],n).y:p(o[U],o[U+1],n).x;return S}function D(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:S(j,3)*a+3*S(j,2)*i*c+3*j*i*i*e+S(i,3)*g,y:S(j,3)*b+3*S(j,2)*i*d+3*j*i*i*f+S(i,3)*h}}function E(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+O.sqrt(k*k-4*j*l))/2/j,n=(-k-O.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return T(m)>"1e12"&&(m=.5),T(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=D(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=D(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+O.sqrt(k*k-4*j*l))/2/j,n=(-k-O.sqrt(k*k-4*j*l))/2/j,T(m)>"1e12"&&(m=.5),T(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=D(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=D(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:Q.apply(0,p),y:Q.apply(0,o)},max:{x:R.apply(0,p),y:R.apply(0,o)}}}function F(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){var c,d;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=b.x+(b.x-(b.bx||b.x)),d=b.y+(b.y-(b.by||b.y)),a=["C",c,d].concat(a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x)),b.qy=b.y+(b.y-(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;)a.splice(b++,0,["C"].concat(c.splice(0,6)));a.splice(b,1),n=R(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],n=R(e.length,g&&g.length||0))},m=0,n=R(e.length,g&&g.length||0);n>m;m++){e[m]=j(e[m],h),k(e,m),g&&(g[m]=j(g[m],i)),g&&k(g,m),l(e,g,h,i,m),l(g,e,i,h,m);var o=e[m],p=g&&g[m],q=o.length,r=g&&p.length;h.x=o[q-2],h.y=o[q-1],h.bx=N(o[q-4])||h.x,h.by=N(o[q-3])||h.y,i.bx=g&&(N(p[r-4])||i.x),i.by=g&&(N(p[r-3])||i.y),i.x=g&&p[r-2],i.y=g&&p[r-1]}return g||(d.curve=f(e)),g?[e,g]:e}function G(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=F(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 H(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 I=b.prototype,J=a.is,K=a._.clone,L="hasOwnProperty",M=/,?([a-z]),?/gi,N=parseFloat,O=Math,P=O.PI,Q=O.min,R=O.max,S=O.pow,T=O.abs,U=h(1),V=h(),W=h(0,1),X=a._unit2px,Y={path:function(a){return a.attr("path")},circle:function(a){var b=X(a);return x(b.cx,b.cy,b.r)},ellipse:function(a){var b=X(a);return x(b.cx,b.cy,b.rx,b.ry)},rect:function(a){var b=X(a);return w(b.x,b.y,b.width,b.height,b.rx,b.ry)},image:function(a){var b=X(a);return w(b.x,b.y,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"),a.attr("y1"),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=U,a.path.getPointAtLength=V,a.path.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return W(a,b).end;var d=W(a,c,1);return b?W(d,b).end:d},I.getTotalLength=function(){return this.node.getTotalLength?this.node.getTotalLength():void 0},I.getPointAtLength=function(a){return V(this.attr("d"),a)},I.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=Y,a.path.toRelative=y,a.path.toAbsolute=z,a.path.toCubic=F,a.path.map=G,a.path.toString=e,a.path.clone=f}),d.plugin(function(a){var b=Math.max,c=Math.min,d=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++)},e=d.prototype;e.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},e.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},e.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},e.remove=function(){for(;this.length;)this.pop().remove();return this},e.attr=function(a){for(var b=0,c=this.items.length;c>b;b++)this.items[b].attr(a);return this},e.clear=function(){for(;this.length;)this.pop()},e.splice=function(a,e){a=0>a?b(this.length+a,0):a,e=b(0,c(this.length-a,e));var f,g=[],h=[],i=[];for(f=2;ff;f++)h.push(this[a+f]);for(;ff?i[f]:g[f-j];for(f=this.items.length=this.length-=e-j;this[f];)delete this[f++];return new d(h)},e.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},e.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},e.getBBox=function(){for(var a=[],d=[],e=[],f=[],g=this.items.length;g--;)if(!this.items[g].removed){var h=this.items[g].getBBox();a.push(h.x),d.push(h.y),e.push(h.x+h.width),f.push(h.y+h.height)}return a=c.apply(0,a),d=c.apply(0,d),e=b.apply(0,e),f=b.apply(0,f),{x:a,y:d,x2:e,y2:f,width:e-a,height:f-d,cx:a+(e-a)/2,cy:d+(f-d)/2}},e.clone=function(a){a=new d;for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},e.toString=function(){return"Snap‘s set"},e.type="set",a.set=function(){var a=new d;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}|…/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){return e=e||"#000",null==d&&(d=4),"string"==typeof d&&(e=d,d=4),null==b&&(b=0,c=2),null==c&&(c=b),e=a.color(e),a.format('',{color:e,dx:b,dy:c,blur:d})},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/demos/snap-ad/src/js/vendor/snap.svg.js b/demos/snap-ad/src/js/vendor/snap.svg.js new file mode 100755 index 0000000..6c9065a --- /dev/null +++ b/demos/snap-ad/src/js/vendor/snap.svg.js @@ -0,0 +1,6925 @@ +// Snap.svg 0.2.0 +// +// 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. +// +// build: 2013-12-23 +// 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. +// ┌────────────────────────────────────────────────────────────┐ \\ +// │ Eve 0.4.2 - JavaScript Events Library │ \\ +// ├────────────────────────────────────────────────────────────┤ \\ +// │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\ +// └────────────────────────────────────────────────────────────┘ \\ + +(function (glob) { + var version = "0.4.2", + has = "hasOwnProperty", + separator = /[\.\/]/, + wildcard = "*", + fun = function () {}, + numsort = function (a, b) { + return a - b; + }, + current_event, + stop, + events = {n: {}}, + /*\ + * eve + [ method ] + + * Fires event with given `name`, given scope and other parameters. + + > Arguments + + - name (string) name of the *event*, dot (`.`) or slash (`/`) separated + - scope (object) context for the event handlers + - varargs (...) the rest of arguments will be sent to event handlers + + = (object) array of returned values from the listeners + \*/ + eve = function (name, scope) { + name = String(name); + var e = events, + oldstop = stop, + args = Array.prototype.slice.call(arguments, 2), + listeners = eve.listeners(name), + z = 0, + f = false, + l, + indexed = [], + queue = {}, + out = [], + ce = current_event, + errors = []; + current_event = name; + stop = 0; + for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) { + indexed.push(listeners[i].zIndex); + if (listeners[i].zIndex < 0) { + queue[listeners[i].zIndex] = listeners[i]; + } + } + indexed.sort(numsort); + while (indexed[z] < 0) { + l = queue[indexed[z++]]; + out.push(l.apply(scope, args)); + if (stop) { + stop = oldstop; + return out; + } + } + for (i = 0; i < ii; i++) { + l = listeners[i]; + if ("zIndex" in l) { + if (l.zIndex == indexed[z]) { + out.push(l.apply(scope, args)); + if (stop) { + break; + } + do { + z++; + l = queue[indexed[z]]; + l && out.push(l.apply(scope, args)); + if (stop) { + break; + } + } while (l) + } else { + queue[l.zIndex] = l; + } + } else { + out.push(l.apply(scope, args)); + if (stop) { + break; + } + } + } + stop = oldstop; + current_event = ce; + return out.length ? out : null; + }; + // Undocumented. Debug only. + eve._events = events; + /*\ + * eve.listeners + [ method ] + + * Internal method which gives you array of all event handlers that will be triggered by the given `name`. + + > Arguments + + - name (string) name of the event, dot (`.`) or slash (`/`) separated + + = (array) array of event handlers + \*/ + eve.listeners = function (name) { + var names = name.split(separator), + e = events, + item, + items, + k, + i, + ii, + j, + jj, + nes, + es = [e], + out = []; + for (i = 0, ii = names.length; i < ii; i++) { + nes = []; + for (j = 0, jj = es.length; j < jj; j++) { + e = es[j].n; + items = [e[names[i]], e[wildcard]]; + k = 2; + while (k--) { + item = items[k]; + if (item) { + nes.push(item); + out = out.concat(item.f || []); + } + } + } + es = nes; + } + return out; + }; + + /*\ + * eve.on + [ method ] + ** + * Binds given event handler with a given name. You can use wildcards “`*`” for the names: + | eve.on("*.under.*", f); + | eve("mouse.under.floor"); // triggers f + * Use @eve to trigger the listener. + ** + > Arguments + ** + - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards + - f (function) event handler function + ** + = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment. + > Example: + | eve.on("mouse", eatIt)(2); + | eve.on("mouse", scream); + | eve.on("mouse", catchIt)(1); + * This will ensure that `catchIt()` function will be called before `eatIt()`. + * + * If you want to put your handler before non-indexed handlers, specify a negative value. + * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”. + \*/ + eve.on = function (name, f) { + name = String(name); + if (typeof f != "function") { + return function () {}; + } + var names = name.split(separator), + e = events; + for (var i = 0, ii = names.length; i < ii; i++) { + e = e.n; + e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}}); + } + e.f = e.f || []; + for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) { + return fun; + } + e.f.push(f); + return function (zIndex) { + if (+zIndex == +zIndex) { + f.zIndex = +zIndex; + } + }; + }; + /*\ + * eve.f + [ method ] + ** + * Returns function that will fire given event with optional arguments. + * Arguments that will be passed to the result function will be also + * concated to the list of final arguments. + | el.onclick = eve.f("click", 1, 2); + | eve.on("click", function (a, b, c) { + | console.log(a, b, c); // 1, 2, [event object] + | }); + > Arguments + - event (string) event name + - varargs (…) and any other arguments + = (function) possible event handler function + \*/ + eve.f = function (event) { + var attrs = [].slice.call(arguments, 1); + return function () { + eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0))); + }; + }; + /*\ + * eve.stop + [ method ] + ** + * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing. + \*/ + eve.stop = function () { + stop = 1; + }; + /*\ + * eve.nt + [ method ] + ** + * Could be used inside event handler to figure out actual name of the event. + ** + > Arguments + ** + - subname (string) #optional subname of the event + ** + = (string) name of the event, if `subname` is not specified + * or + = (boolean) `true`, if current event’s name contains `subname` + \*/ + eve.nt = function (subname) { + if (subname) { + return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event); + } + return current_event; + }; + /*\ + * eve.nts + [ method ] + ** + * Could be used inside event handler to figure out actual name of the event. + ** + ** + = (array) names of the event + \*/ + eve.nts = function () { + return current_event.split(separator); + }; + /*\ + * eve.off + [ method ] + ** + * Removes given function from the list of event listeners assigned to given name. + * If no arguments specified all the events will be cleared. + ** + > Arguments + ** + - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards + - f (function) event handler function + \*/ + /*\ + * eve.unbind + [ method ] + ** + * See @eve.off + \*/ + eve.off = eve.unbind = function (name, f) { + if (!name) { + eve._events = events = {n: {}}; + return; + } + var names = name.split(separator), + e, + key, + splice, + i, ii, j, jj, + cur = [events]; + for (i = 0, ii = names.length; i < ii; i++) { + for (j = 0; j < cur.length; j += splice.length - 2) { + splice = [j, 1]; + e = cur[j].n; + if (names[i] != wildcard) { + if (e[names[i]]) { + splice.push(e[names[i]]); + } + } else { + for (key in e) if (e[has](key)) { + splice.push(e[key]); + } + } + cur.splice.apply(cur, splice); + } + } + for (i = 0, ii = cur.length; i < ii; i++) { + e = cur[i]; + while (e.n) { + if (f) { + if (e.f) { + for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) { + e.f.splice(j, 1); + break; + } + !e.f.length && delete e.f; + } + for (key in e.n) if (e.n[has](key) && e.n[key].f) { + var funcs = e.n[key].f; + for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) { + funcs.splice(j, 1); + break; + } + !funcs.length && delete e.n[key].f; + } + } else { + delete e.f; + for (key in e.n) if (e.n[has](key) && e.n[key].f) { + delete e.n[key].f; + } + } + e = e.n; + } + } + }; + /*\ + * eve.once + [ method ] + ** + * Binds given event handler with a given name to only run once then unbind itself. + | eve.once("login", f); + | eve("login"); // triggers f + | eve("login"); // no listeners + * Use @eve to trigger the listener. + ** + > Arguments + ** + - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards + - f (function) event handler function + ** + = (function) same return function as @eve.on + \*/ + eve.once = function (name, f) { + var f2 = function () { + eve.unbind(name, f2); + return f.apply(this, arguments); + }; + return eve.on(name, f2); + }; + /*\ + * eve.version + [ property (string) ] + ** + * Current version of the library. + \*/ + eve.version = version; + eve.toString = function () { + return "You are running Eve " + version; + }; + (typeof module != "undefined" && module.exports) ? (module.exports = eve) : (typeof define != "undefined" ? (define("eve", [], function() { return eve; })) : (glob.eve = eve)); +})(this); + +(function (glob, factory) { + // AMD support + if (typeof define === "function" && define.amd) { + // Define as an anonymous module + define(["eve"], function( eve ) { + return factory(glob, eve); + }); + } else { + // Browser globals (glob is window) + // Snap adds itself to window + factory(glob, glob.eve); + } +}(this, function (window, eve) { +// 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. +var mina = (function (eve) { + var animations = {}, + requestAnimFrame = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { + setTimeout(callback, 16); + }, + isArray = Array.isArray || function (a) { + return a instanceof Array || + Object.prototype.toString.call(a) == "[object Array]"; + }, + idgen = 0, + idprefix = "M" + (+new Date).toString(36), + ID = function () { + return idprefix + (idgen++).toString(36); + }, + diff = function (a, b, A, B) { + if (isArray(a)) { + res = []; + for (var i = 0, ii = a.length; i < ii; i++) { + res[i] = diff(a[i], b, A[i], B); + } + return res; + } + var dif = (A - a) / (B - b); + return function (bb) { + return a + dif * (bb - b); + }; + }, + timer = Date.now || function () { + return +new Date; + }, + sta = function (val) { + var a = this; + if (val == null) { + return a.s; + } + var ds = a.s - val; + a.b += a.dur * ds; + a.B += a.dur * ds; + a.s = val; + }, + speed = function (val) { + var a = this; + if (val == null) { + return a.spd; + } + a.spd = val; + }, + duration = function (val) { + var a = this; + if (val == null) { + return a.dur; + } + a.s = a.s * val / a.dur; + a.dur = val; + }, + stopit = function () { + var a = this; + delete animations[a.id]; + eve("mina.stop." + a.id, a); + }, + pause = function () { + var a = this; + if (a.pdif) { + return; + } + delete animations[a.id]; + a.pdif = a.get() - a.b; + }, + resume = function () { + var a = this; + if (!a.pdif) { + return; + } + a.b = a.get() - a.pdif; + delete a.pdif; + animations[a.id] = a; + }, + frame = function () { + var len = 0; + for (var i in animations) if (animations.hasOwnProperty(i)) { + var a = animations[i], + b = a.get(), + res; + len++; + a.s = (b - a.b) / (a.dur / a.spd); + if (a.s >= 1) { + delete animations[i]; + a.s = 1; + len--; + (function (a) { + setTimeout(function () { + eve("mina.finish." + a.id, a); + }); + }(a)); + } + if (isArray(a.start)) { + res = []; + for (var j = 0, jj = a.start.length; j < jj; j++) { + res[j] = +a.start[j] + + (a.end[j] - a.start[j]) * a.easing(a.s); + } + } else { + res = +a.start + (a.end - a.start) * a.easing(a.s); + } + a.set(res); + } + len && requestAnimFrame(frame); + }, + // SIERRA Unfamiliar with the word _slave_ in this context. Also, I don't know what _gereal_ means. Do you mean _general_? + /*\ + * mina + [ method ] + ** + * Generic animation of numbers + ** + - a (number) start _slave_ number + - A (number) end _slave_ number + - b (number) start _master_ number (start time in general case) + - B (number) end _master_ number (end time in gereal case) + - get (function) getter of _master_ number (see @mina.time) + - set (function) setter of _slave_ number + - easing (function) #optional easing function, default is @mina.linear + = (object) animation descriptor + o { + o id (string) animation id, + o start (number) start _slave_ number, + o end (number) end _slave_ number, + o b (number) start _master_ number, + o s (number) animation status (0..1), + o dur (number) animation duration, + o spd (number) animation speed, + o get (function) getter of _master_ number (see @mina.time), + o set (function) setter of _slave_ number, + o easing (function) easing function, default is @mina.linear, + o status (function) status getter/setter, + o speed (function) speed getter/setter, + o duration (function) duration getter/setter, + o stop (function) animation stopper + o } + \*/ + mina = function (a, A, b, B, get, set, easing) { + var anim = { + id: ID(), + start: a, + end: A, + b: b, + s: 0, + dur: B - b, + spd: 1, + get: get, + set: set, + easing: easing || mina.linear, + status: sta, + speed: speed, + duration: duration, + stop: stopit, + pause: pause, + resume: resume + }; + animations[anim.id] = anim; + var len = 0, i; + for (i in animations) if (animations.hasOwnProperty(i)) { + len++; + if (len == 2) { + break; + } + } + len == 1 && requestAnimFrame(frame); + return anim; + }; + /*\ + * mina.time + [ method ] + ** + * Returns the current time. Equivalent to: + | function () { + | return (new Date).getTime(); + | } + \*/ + mina.time = timer; + /*\ + * mina.getById + [ method ] + ** + * Returns an animation by its id + - id (string) animation's id + = (object) See @mina + \*/ + mina.getById = function (id) { + return animations[id] || null; + }; + + /*\ + * mina.linear + [ method ] + ** + * Default linear easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.linear = function (n) { + return n; + }; + /*\ + * mina.easeout + [ method ] + ** + * Easeout easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.easeout = function (n) { + return Math.pow(n, 1.7); + }; + /*\ + * mina.easein + [ method ] + ** + * Easein easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.easein = function (n) { + return Math.pow(n, .48); + }; + /*\ + * mina.easeinout + [ method ] + ** + * Easeinout easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.easeinout = function (n) { + if (n == 1) { + return 1; + } + if (n == 0) { + return 0; + } + var q = .48 - n / 1.04, + Q = Math.sqrt(.1734 + q * q), + x = Q - q, + X = Math.pow(Math.abs(x), 1 / 3) * (x < 0 ? -1 : 1), + y = -Q - q, + Y = Math.pow(Math.abs(y), 1 / 3) * (y < 0 ? -1 : 1), + t = X + Y + .5; + return (1 - t) * 3 * t * t + t * t * t; + }; + /*\ + * mina.backin + [ method ] + ** + * Backin easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.backin = function (n) { + if (n == 1) { + return 1; + } + var s = 1.70158; + return n * n * ((s + 1) * n - s); + }; + /*\ + * mina.backout + [ method ] + ** + * Backout easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.backout = function (n) { + if (n == 0) { + return 0; + } + n = n - 1; + var s = 1.70158; + return n * n * ((s + 1) * n + s) + 1; + }; + /*\ + * mina.elastic + [ method ] + ** + * Elastic easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.elastic = function (n) { + if (n == !!n) { + return n; + } + return Math.pow(2, -10 * n) * Math.sin((n - .075) * + (2 * Math.PI) / .3) + 1; + }; + /*\ + * mina.bounce + [ method ] + ** + * Bounce easing + - n (number) input 0..1 + = (number) output 0..1 + \*/ + mina.bounce = function (n) { + var s = 7.5625, + p = 2.75, + l; + if (n < (1 / p)) { + l = s * n * n; + } else { + if (n < (2 / p)) { + n -= (1.5 / p); + l = s * n * n + .75; + } else { + if (n < (2.5 / p)) { + n -= (2.25 / p); + l = s * n * n + .9375; + } else { + n -= (2.625 / p); + l = s * n * n + .984375; + } + } + } + return l; + }; + window.mina = mina; + return mina; +})(typeof eve == "undefined" ? function () {} : eve); +// 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. + +var Snap = (function() { +Snap.version = "0.2.0"; +/*\ + * Snap + [ method ] + ** + * Creates a drawing surface or wraps existing SVG element. + ** + - width (number|string) width of surface + - height (number|string) height of surface + * or + - DOM (SVGElement) element to be wrapped into Snap structure + * or + - query (string) CSS query selector + = (object) @Element +\*/ +function Snap(w, h) { + if (w) { + if (w.tagName) { + return wrap(w); + } + if (w instanceof Element) { + return w; + } + if (h == null) { + w = glob.doc.querySelector(w); + return wrap(w); + } + } + w = w == null ? "100%" : w; + h = h == null ? "100%" : h; + return new Paper(w, h); +} +Snap.toString = function () { + return "Snap v" + this.version; +}; +Snap._ = {}; +var glob = { + win: window, + doc: window.document +}; +Snap._.glob = glob; +var has = "hasOwnProperty", + Str = String, + toFloat = parseFloat, + toInt = parseInt, + math = Math, + mmax = math.max, + mmin = math.min, + abs = math.abs, + pow = math.pow, + PI = math.PI, + round = math.round, + E = "", + S = " ", + objectToString = Object.prototype.toString, + ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i, + colourRegExp = /^\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, + 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 + "]+"), + whitespace = new RegExp("[" + spaces + "]", "g"), + commaSpaces = new RegExp("[" + spaces + "]*,[" + spaces + "]*"), + hsrg = {hs: 1, rg: 1}, + pathCommand = new RegExp("([a-z])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"), + tCommand = new RegExp("([rstm])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"), + pathValues = new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[" + spaces + "]*,?[" + spaces + "]*", "ig"), + idgen = 0, + idprefix = "S" + (+new Date).toString(36), + ID = function () { + return idprefix + (idgen++).toString(36); + }, + xlink = "http://www.w3.org/1999/xlink", + xmlns = "http://www.w3.org/2000/svg", + hub = {}, + URL = Snap.url = function (url) { + return "url('#" + url + "')"; + }; + +function $(el, attr) { + if (attr) { + if (typeof el == "string") { + el = $(el); + } + if (typeof attr == "string") { + if (attr.substring(0, 6) == "xlink:") { + return el.getAttributeNS(xlink, attr.substring(6)); + } + if (attr.substring(0, 4) == "xml:") { + return el.getAttributeNS(xmlns, attr.substring(4)); + } + return el.getAttribute(attr); + } + for (var key in attr) if (attr[has](key)) { + var val = Str(attr[key]); + if (val) { + if (key.substring(0, 6) == "xlink:") { + el.setAttributeNS(xlink, key.substring(6), val); + } else if (key.substring(0, 4) == "xml:") { + el.setAttributeNS(xmlns, key.substring(4), val); + } else { + el.setAttribute(key, val); + } + } else { + el.removeAttribute(key); + } + } + } else { + el = glob.doc.createElementNS(xmlns, el); + // el.style && (el.style.webkitTapHighlightColor = "rgba(0,0,0,0)"); + } + return el; +} +Snap._.$ = $; +Snap._.id = ID; +function getAttrs(el) { + var attrs = el.attributes, + name, + out = {}; + for (var i = 0; i < attrs.length; i++) { + if (attrs[i].namespaceURI == xlink) { + name = "xlink:"; + } else { + name = ""; + } + name += attrs[i].name; + out[name] = attrs[i].textContent; + } + return out; +} +function is(o, type) { + type = Str.prototype.toLowerCase.call(type); + if (type == "finite") { + return isFinite(o); + } + if (type == "array" && + (o instanceof Array || Array.isArray && Array.isArray(o))) { + return true; + } + return (type == "null" && o === null) || + (type == typeof o && o !== null) || + (type == "object" && o === Object(o)) || + objectToString.call(o).slice(8, -1).toLowerCase() == type; +} +/*\ + * Snap.format + [ method ] + ** + * Replaces construction of type `{}` to the corresponding argument + ** + - token (string) string to format + - json (object) object which properties are used as a replacement + = (string) formatted string + > Usage + | // this draws a rectangular shape equivalent to "M10,20h40v50h-40z" + | paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z", { + | x: 10, + | y: 20, + | dim: { + | width: 40, + | height: 50, + | "negative width": -40 + | } + | })); +\*/ +Snap.format = (function () { + var tokenRegex = /\{([^\}]+)\}/g, + objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties + replacer = function (all, key, obj) { + var res = obj; + key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) { + name = name || quotedName; + if (res) { + if (name in res) { + res = res[name]; + } + typeof res == "function" && isFunc && (res = res()); + } + }); + res = (res == null || res == obj ? all : res) + ""; + return res; + }; + return function (str, obj) { + return Str(str).replace(tokenRegex, function (all, key) { + return replacer(all, key, obj); + }); + }; +})(); +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; + } + var res = new obj.constructor; + for (var key in obj) if (obj[has](key)) { + res[key] = clone(obj[key]); + } + return res; +} +Snap._.clone = clone; +function repush(array, item) { + for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) { + return array.push(array.splice(i, 1)[0]); + } +} +function cacher(f, scope, postprocessor) { + function newf() { + var arg = Array.prototype.slice.call(arguments, 0), + args = arg.join("\u2400"), + cache = newf.cache = newf.cache || {}, + count = newf.count = newf.count || []; + if (cache[has](args)) { + repush(count, args); + return postprocessor ? postprocessor(cache[args]) : cache[args]; + } + count.length >= 1e3 && delete cache[count.shift()]; + count.push(args); + cache[args] = f.apply(scope, arg); + return postprocessor ? postprocessor(cache[args]) : cache[args]; + } + return newf; +} +Snap._.cacher = cacher; +function angle(x1, y1, x2, y2, x3, y3) { + if (x3 == null) { + var x = x1 - x2, + y = y1 - y2; + if (!x && !y) { + return 0; + } + return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360; + } else { + return angle(x1, y1, x3, y3) - angle(x2, y2, x3, y3); + } +} +function rad(deg) { + return deg % 360 * PI / 180; +} +function deg(rad) { + return rad * 180 / PI % 360; +} +function x_y() { + return this.x + S + this.y; +} +function x_y_w_h() { + return this.x + S + this.y + S + this.width + " \xd7 " + this.height; +} + +/*\ + * Snap.rad + [ method ] + ** + * Transform angle to radians + - deg (number) angle in degrees + = (number) angle in radians +\*/ +Snap.rad = rad; +/*\ + * Snap.deg + [ method ] + ** + * Transform angle to degrees + - rad (number) angle in radians + = (number) angle in degrees +\*/ +Snap.deg = deg; +// SIERRA for which point is the angle calculated? +/*\ + * Snap.angle + [ method ] + ** + * Returns an angle between two or three points + > Parameters + - x1 (number) x coord of first point + - y1 (number) y coord of first point + - x2 (number) x coord of second point + - y2 (number) y coord of second point + - x3 (number) #optional x coord of third point + - y3 (number) #optional y coord of third point + = (number) angle in degrees +\*/ +Snap.angle = angle; +/*\ + * Snap.is + [ method ] + ** + * Handy replacement for the `typeof` operator + - o (…) any object or primitive + - type (string) name of the type, e.g., `string`, `function`, `number`, etc. + = (boolean) `true` if given value is of given type +\*/ +Snap.is = is; +/*\ + * Snap.snapTo + [ method ] + ** + * Snaps given value to given grid + - values (array|number) given array of values or step of the grid + - value (number) value to adjust + - tolerance (number) #optional maximum distance to the target value that would trigger the snap. Default is `10`. + = (number) adjusted value +\*/ +Snap.snapTo = function (values, value, tolerance) { + tolerance = is(tolerance, "finite") ? tolerance : 10; + if (is(values, "array")) { + var i = values.length; + while (i--) if (abs(values[i] - value) <= tolerance) { + return values[i]; + } + } else { + values = +values; + var rem = value % values; + if (rem < tolerance) { + return value - rem; + } + if (rem > values - tolerance) { + return value - rem + values; + } + } + 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.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; + + // 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.isSimple) { + 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 + [ method ] + ** + * Parses color string as RGB object + - color (string) color string in one of the following formats: + #

      + * Note that `%` can be used any time: `rgb(20%, 255, 50%)`. + = (object) RGB object in the following format: + o { + o r (number) red, + o g (number) green, + o b (number) blue, + o hex (string) color in HTML/CSS format: #••••••, + o error (boolean) true if string can't be parsed + o } +\*/ +Snap.getRGB = cacher(function (colour) { + if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) { + return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString}; + } + if (colour == "none") { + return {r: -1, g: -1, b: -1, hex: "none", toString: rgbtoString}; + } + !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour)); + if (!colour) { + return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString}; + } + var res, + red, + green, + blue, + opacity, + t, + values, + rgb = colour.match(colourRegExp); + if (rgb) { + if (rgb[2]) { + blue = toInt(rgb[2].substring(5), 16); + green = toInt(rgb[2].substring(3, 5), 16); + red = toInt(rgb[2].substring(1, 3), 16); + } + if (rgb[3]) { + blue = toInt((t = rgb[3].charAt(3)) + t, 16); + green = toInt((t = rgb[3].charAt(2)) + t, 16); + red = toInt((t = rgb[3].charAt(1)) + t, 16); + } + if (rgb[4]) { + values = rgb[4].split(commaSpaces); + red = toFloat(values[0]); + values[0].slice(-1) == "%" && (red *= 2.55); + green = toFloat(values[1]); + values[1].slice(-1) == "%" && (green *= 2.55); + blue = toFloat(values[2]); + values[2].slice(-1) == "%" && (blue *= 2.55); + rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3])); + values[3] && values[3].slice(-1) == "%" && (opacity /= 100); + } + if (rgb[5]) { + values = rgb[5].split(commaSpaces); + red = toFloat(values[0]); + values[0].slice(-1) == "%" && (red /= 100); + green = toFloat(values[1]); + values[1].slice(-1) == "%" && (green /= 100); + blue = toFloat(values[2]); + values[2].slice(-1) == "%" && (blue /= 100); + (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); + rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3])); + values[3] && values[3].slice(-1) == "%" && (opacity /= 100); + return Snap.hsb2rgb(red, green, blue, opacity); + } + if (rgb[6]) { + values = rgb[6].split(commaSpaces); + red = toFloat(values[0]); + values[0].slice(-1) == "%" && (red /= 100); + green = toFloat(values[1]); + values[1].slice(-1) == "%" && (green /= 100); + blue = toFloat(values[2]); + values[2].slice(-1) == "%" && (blue /= 100); + (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); + rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3])); + values[3] && values[3].slice(-1) == "%" && (opacity /= 100); + return Snap.hsl2rgb(red, green, blue, opacity); + } + red = mmin(math.round(red), 255); + green = mmin(math.round(green), 255); + blue = mmin(math.round(blue), 255); + opacity = mmin(mmax(opacity, 0), 1); + rgb = {r: red, g: green, b: blue, toString: rgbtoString}; + rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1); + rgb.opacity = is(opacity, "finite") ? opacity : 1; + return rgb; + } + return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString}; +}, Snap); +// SIERRA It seems odd that the following 3 conversion methods are not expressed as .this2that(), like the others. +/*\ + * Snap.hsb + [ method ] + ** + * Converts HSB values to a hex representation of the color + - h (number) hue + - s (number) saturation + - b (number) value or brightness + = (string) hex representation of the color +\*/ +Snap.hsb = cacher(function (h, s, b) { + return Snap.hsb2rgb(h, s, b).hex; +}); +/*\ + * Snap.hsl + [ method ] + ** + * Converts HSL values to a hex representation of the color + - h (number) hue + - s (number) saturation + - l (number) luminosity + = (string) hex representation of the color +\*/ +Snap.hsl = cacher(function (h, s, l) { + return Snap.hsl2rgb(h, s, l).hex; +}); +/*\ + * Snap.rgb + [ method ] + ** + * Converts RGB values to a hex representation of the color + - r (number) red + - g (number) green + - b (number) blue + = (string) hex representation of the color +\*/ +Snap.rgb = cacher(function (r, g, b, o) { + if (is(o, "finite")) { + var round = math.round; + return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")"; + } + return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1); +}); +var toHex = function (color) { + var i = glob.doc.getElementsByTagName("head")[0], + red = "rgb(255, 0, 0)"; + toHex = cacher(function (color) { + if (color.toLowerCase() == "red") { + return red; + } + i.style.color = red; + i.style.color = color; + var out = glob.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color"); + return out == red ? null : out; + }); + return toHex(color); +}, +hsbtoString = function () { + return "hsb(" + [this.h, this.s, this.b] + ")"; +}, +hsltoString = function () { + return "hsl(" + [this.h, this.s, this.l] + ")"; +}, +rgbtoString = function () { + return this.opacity == 1 || this.opacity == null ? + this.hex : + "rgba(" + [this.r, this.g, this.b, this.opacity] + ")"; +}, +prepareRGB = function (r, g, b) { + if (g == null && is(r, "object") && "r" in r && "g" in r && "b" in r) { + b = r.b; + g = r.g; + r = r.r; + } + if (g == null && is(r, string)) { + var clr = Snap.getRGB(r); + r = clr.r; + g = clr.g; + b = clr.b; + } + if (r > 1 || g > 1 || b > 1) { + r /= 255; + g /= 255; + b /= 255; + } + + return [r, g, b]; +}, +packageRGB = function (r, g, b, o) { + r = math.round(r * 255); + g = math.round(g * 255); + b = math.round(b * 255); + var rgb = { + r: r, + g: g, + b: b, + opacity: is(o, "finite") ? o : 1, + hex: Snap.rgb(r, g, b), + toString: rgbtoString + }; + is(o, "finite") && (rgb.opacity = o); + return rgb; +}; +// SIERRA Clarify if Snap does not support consolidated HSLA/RGBA colors. E.g., can you specify a semi-transparent value for Snap.filter.shadow()? +/*\ + * Snap.color + [ method ] + ** + * Parses the color string and returns an object featuring the color's component values + - clr (string) color string in one of the supported formats (see @Snap.getRGB) + = (object) Combined RGB/HSB object in the following format: + o { + o r (number) red, + o g (number) green, + o b (number) blue, + o hex (string) color in HTML/CSS format: #••••••, + o error (boolean) `true` if string can't be parsed, + o h (number) hue, + o s (number) saturation, + o v (number) value (brightness), + o l (number) lightness + o } +\*/ +Snap.color = function (clr) { + var rgb; + if (is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) { + rgb = Snap.hsb2rgb(clr); + clr.r = rgb.r; + clr.g = rgb.g; + clr.b = rgb.b; + clr.opacity = 1; + clr.hex = rgb.hex; + } else if (is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) { + rgb = Snap.hsl2rgb(clr); + clr.r = rgb.r; + clr.g = rgb.g; + clr.b = rgb.b; + clr.opacity = 1; + clr.hex = rgb.hex; + } else { + if (is(clr, "string")) { + clr = Snap.getRGB(clr); + } + if (is(clr, "object") && "r" in clr && "g" in clr && "b" in clr && !("error" in clr)) { + rgb = Snap.rgb2hsl(clr); + clr.h = rgb.h; + clr.s = rgb.s; + clr.l = rgb.l; + rgb = Snap.rgb2hsb(clr); + clr.v = rgb.b; + } else { + clr = {hex: "none"}; + clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1; + clr.error = 1; + } + } + clr.toString = rgbtoString; + return clr; +}; +/*\ + * Snap.hsb2rgb + [ method ] + ** + * Converts HSB values to an RGB object + - h (number) hue + - s (number) saturation + - v (number) value or brightness + = (object) RGB object in the following format: + o { + o r (number) red, + o g (number) green, + o b (number) blue, + o hex (string) color in HTML/CSS format: #•••••• + o } +\*/ +Snap.hsb2rgb = function (h, s, v, o) { + if (is(h, "object") && "h" in h && "s" in h && "b" in h) { + v = h.b; + s = h.s; + h = h.h; + o = h.o; + } + h *= 360; + var R, G, B, X, C; + h = (h % 360) / 60; + C = v * s; + X = C * (1 - abs(h % 2 - 1)); + R = G = B = v - C; + + h = ~~h; + R += [C, X, 0, 0, X, C][h]; + G += [X, C, C, X, 0, 0][h]; + B += [0, 0, X, C, C, X][h]; + return packageRGB(R, G, B, o); +}; +/*\ + * Snap.hsl2rgb + [ method ] + ** + * Converts HSL values to an RGB object + - h (number) hue + - s (number) saturation + - l (number) luminosity + = (object) RGB object in the following format: + o { + o r (number) red, + o g (number) green, + o b (number) blue, + o hex (string) color in HTML/CSS format: #•••••• + o } +\*/ +Snap.hsl2rgb = function (h, s, l, o) { + if (is(h, "object") && "h" in h && "s" in h && "l" in h) { + l = h.l; + s = h.s; + h = h.h; + } + if (h > 1 || s > 1 || l > 1) { + h /= 360; + s /= 100; + l /= 100; + } + h *= 360; + var R, G, B, X, C; + h = (h % 360) / 60; + C = 2 * s * (l < .5 ? l : 1 - l); + X = C * (1 - abs(h % 2 - 1)); + R = G = B = l - C / 2; + + h = ~~h; + R += [C, X, 0, 0, X, C][h]; + G += [X, C, C, X, 0, 0][h]; + B += [0, 0, X, C, C, X][h]; + return packageRGB(R, G, B, o); +}; +/*\ + * Snap.rgb2hsb + [ method ] + ** + * Converts RGB values to an HSB object + - r (number) red + - g (number) green + - b (number) blue + = (object) HSB object in the following format: + o { + o h (number) hue, + o s (number) saturation, + o b (number) brightness + o } +\*/ +Snap.rgb2hsb = function (r, g, b) { + b = prepareRGB(r, g, b); + r = b[0]; + g = b[1]; + b = b[2]; + + var H, S, V, C; + V = mmax(r, g, b); + C = V - mmin(r, g, b); + H = (C == 0 ? null : + V == r ? (g - b) / C : + V == g ? (b - r) / C + 2 : + (r - g) / C + 4 + ); + H = ((H + 360) % 6) * 60 / 360; + S = C == 0 ? 0 : C / V; + return {h: H, s: S, b: V, toString: hsbtoString}; +}; +/*\ + * Snap.rgb2hsl + [ method ] + ** + * Converts RGB values to an HSL object + - r (number) red + - g (number) green + - b (number) blue + = (object) HSL object in the following format: + o { + o h (number) hue, + o s (number) saturation, + o l (number) luminosity + o } +\*/ +Snap.rgb2hsl = function (r, g, b) { + b = prepareRGB(r, g, b); + r = b[0]; + g = b[1]; + b = b[2]; + + var H, S, L, M, m, C; + M = mmax(r, g, b); + m = mmin(r, g, b); + C = M - m; + H = (C == 0 ? null : + M == r ? (g - b) / C : + M == g ? (b - r) / C + 2 : + (r - g) / C + 4); + H = ((H + 360) % 6) * 60 / 360; + L = (M + m) / 2; + S = (C == 0 ? 0 : + L < .5 ? C / (2 * L) : + C / (2 - 2 * L)); + return {h: H, s: S, l: L, toString: hsltoString}; +}; + +// Transformations +// SIERRA Snap.parsePathString(): By _array of arrays,_ I assume you mean a format like this for two separate segments? [ ["M10,10","L90,90"], ["M90,10","L10,90"] ] Otherwise how is each command structured? +/*\ + * Snap.parsePathString + [ method ] + ** + * Utility method + ** + * Parses given path string into an array of arrays of path segments + - pathString (string|array) path string or array of segments (in the last case it is returned straight away) + = (array) array of segments +\*/ +Snap.parsePathString = function (pathString) { + if (!pathString) { + return null; + } + var pth = Snap.path(pathString); + if (pth.arr) { + return Snap.path.clone(pth.arr); + } + + var paramCounts = {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}, + data = []; + if (is(pathString, "array") && is(pathString[0], "array")) { // rough assumption + data = Snap.path.clone(pathString); + } + if (!data.length) { + Str(pathString).replace(pathCommand, function (a, b, c) { + var params = [], + name = b.toLowerCase(); + c.replace(pathValues, function (a, b) { + b && params.push(+b); + }); + if (name == "m" && params.length > 2) { + data.push([b].concat(params.splice(0, 2))); + name = "l"; + b = b == "m" ? "l" : "L"; + } + if (name == "o" && params.length == 1) { + data.push([b, params[0]]); + } + if (name == "r") { + data.push([b].concat(params)); + } else while (params.length >= paramCounts[name]) { + data.push([b].concat(params.splice(0, paramCounts[name]))); + if (!paramCounts[name]) { + break; + } + } + }); + } + data.toString = Snap.path.toString; + pth.arr = Snap.path.clone(data); + return data; +}; +/*\ + * Snap.parseTransformString + [ method ] + ** + * Utility method + ** + * Parses given transform string into an array of transformations + - TString (string|array) transform string or array of transformations (in the last case it is returned straight away) + = (array) array of transformations +\*/ +var parseTransformString = Snap.parseTransformString = function (TString) { + if (!TString) { + return null; + } + var paramCounts = {r: 3, s: 4, t: 2, m: 6}, + data = []; + if (is(TString, "array") && is(TString[0], "array")) { // rough assumption + data = Snap.path.clone(TString); + } + if (!data.length) { + Str(TString).replace(tCommand, function (a, b, c) { + var params = [], + name = b.toLowerCase(); + c.replace(pathValues, function (a, b) { + b && params.push(+b); + }); + data.push([b].concat(params)); + }); + } + data.toString = Snap.path.toString; + return data; +}; +function svgTransform2string(tstr) { + var res = []; + tstr = tstr.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g, function (all, name, params) { + params = params.split(/\s*,\s*|\s+/); + if (name == "rotate" && params.length == 1) { + params.push(0, 0); + } + if (name == "scale") { + if (params.length == 2) { + params.push(0, 0); + } + if (params.length == 1) { + params.push(params[0], 0, 0); + } + } + if (name == "skewX") { + res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]); + } else if (name == "skewY") { + res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]); + } else { + res.push([name.charAt(0)].concat(params)); + } + return all; + }); + return res; +} +Snap._.svgTransform2string = svgTransform2string; +Snap._.rgTransform = new RegExp("^[a-z][" + spaces + "]*-?\\.?\\d", "i"); +function transform2matrix(tstr, bbox) { + var tdata = parseTransformString(tstr), + m = new Matrix; + if (tdata) { + for (var i = 0, ii = tdata.length; i < ii; i++) { + var t = tdata[i], + tlen = t.length, + command = Str(t[0]).toLowerCase(), + absolute = t[0] != command, + inver = absolute ? m.invert() : 0, + x1, + y1, + x2, + y2, + bb; + if (command == "t" && tlen == 2){ + m.translate(t[1], 0); + } else if (command == "t" && tlen == 3) { + if (absolute) { + x1 = inver.x(0, 0); + y1 = inver.y(0, 0); + x2 = inver.x(t[1], t[2]); + y2 = inver.y(t[1], t[2]); + m.translate(x2 - x1, y2 - y1); + } else { + m.translate(t[1], t[2]); + } + } else if (command == "r") { + if (tlen == 2) { + bb = bb || bbox; + m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2); + } else if (tlen == 4) { + if (absolute) { + x2 = inver.x(t[2], t[3]); + y2 = inver.y(t[2], t[3]); + m.rotate(t[1], x2, y2); + } else { + m.rotate(t[1], t[2], t[3]); + } + } + } else if (command == "s") { + if (tlen == 2 || tlen == 3) { + bb = bb || bbox; + m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2); + } else if (tlen == 4) { + if (absolute) { + x2 = inver.x(t[2], t[3]); + y2 = inver.y(t[2], t[3]); + m.scale(t[1], t[1], x2, y2); + } else { + m.scale(t[1], t[1], t[2], t[3]); + } + } else if (tlen == 5) { + if (absolute) { + x2 = inver.x(t[3], t[4]); + y2 = inver.y(t[3], t[4]); + m.scale(t[1], t[2], x2, y2); + } else { + m.scale(t[1], t[2], t[3], t[4]); + } + } + } else if (command == "m" && tlen == 7) { + m.add(t[1], t[2], t[3], t[4], t[5], t[6]); + } + } + } + return m; +} +Snap._.transform2matrix = transform2matrix; +function extractTransform(el, tstr) { + if (tstr == null) { + var doReturn = true; + if (el.type == "linearGradient" || el.type == "radialGradient") { + tstr = el.node.getAttribute("gradientTransform"); + } else if (el.type == "pattern") { + tstr = el.node.getAttribute("patternTransform"); + } else { + tstr = el.node.getAttribute("transform"); + } + if (!tstr) { + return new Matrix; + } + tstr = svgTransform2string(tstr); + } else { + if (!Snap._.rgTransform.test(tstr)) { + tstr = svgTransform2string(tstr); + } else { + tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E); + } + if (is(tstr, "array")) { + tstr = Snap.path ? Snap.path.toString.call(tstr) : Str(tstr); + } + el._.transform = tstr; + } + var m = transform2matrix(tstr, el.getBBox(1)); + if (doReturn) { + return m; + } else { + el.matrix = m; + } +} +Snap._unit2px = unit2px; +var contains = glob.doc.contains || glob.doc.compareDocumentPosition ? + function (a, b) { + var adown = a.nodeType == 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a == bup || !!(bup && bup.nodeType == 1 && ( + adown.contains ? + adown.contains(bup) : + a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16 + )); + } : + function (a, b) { + if (b) { + while (b) { + b = b.parentNode; + if (b == a) { + return true; + } + } + } + return false; + }; +function getSomeDefs(el) { + var cache = Snap._.someDefs; + if (cache && contains(cache.ownerDocument.documentElement, cache)) { + return cache; + } + var p = (el.node.ownerSVGElement && wrap(el.node.ownerSVGElement)) || + (el.node.parentNode && wrap(el.node.parentNode)) || + Snap.select("svg") || + Snap(0, 0), + pdefs = p.select("defs"), + defs = pdefs == null ? false : pdefs.node; + if (!defs) { + defs = make("defs", p.node).node; + } + Snap._.someDefs = defs; + return defs; +} +Snap._.getSomeDefs = getSomeDefs; +function unit2px(el, name, value) { + var defs = getSomeDefs(el), + out = {}, + mgr = defs.querySelector(".svg---mgr"); + if (!mgr) { + mgr = $("rect"); + $(mgr, {width: 10, height: 10, "class": "svg---mgr"}); + defs.appendChild(mgr); + } + function getW(val) { + if (val == null) { + return E; + } + if (val == +val) { + return val; + } + $(mgr, {width: val}); + return mgr.getBBox().width; + } + function getH(val) { + if (val == null) { + return E; + } + if (val == +val) { + return val; + } + $(mgr, {height: val}); + return mgr.getBBox().height; + } + function set(nam, f) { + if (name == null) { + out[nam] = f(el.attr(nam)); + } else if (nam == name) { + out = f(value == null ? el.attr(nam) : value); + } + } + switch (el.type) { + case "rect": + set("rx", getW); + set("ry", getH); + case "image": + set("width", getW); + set("height", getH); + case "text": + set("x", getW); + set("y", getH); + break; + case "circle": + set("cx", getW); + set("cy", getH); + set("r", getW); + break; + case "ellipse": + set("cx", getW); + set("cy", getH); + set("rx", getW); + set("ry", getH); + break; + case "line": + set("x1", getW); + set("x2", getW); + set("y1", getH); + set("y2", getH); + break; + case "marker": + set("refX", getW); + set("markerWidth", getW); + set("refY", getH); + set("markerHeight", getH); + break; + case "radialGradient": + set("fx", getW); + set("fy", getH); + break; + case "tspan": + set("dx", getW); + set("dy", getH); + break; + default: + set(name, getW); + } + return out; +} +/*\ + * Snap.select + [ method ] + ** + * Wraps a DOM element specified by CSS selector as @Element + - query (string) CSS selector of the element + = (Element) the current element +\*/ +Snap.select = function (query) { + return wrap(glob.doc.querySelector(query)); +}; +/*\ + * Snap.selectAll + [ method ] + ** + * Wraps DOM elements specified by CSS selector as set or array of @Element + - query (string) CSS selector of the element + = (Element) the current element +\*/ +Snap.selectAll = function (query) { + var nodelist = glob.doc.querySelectorAll(query), + set = (Snap.set || Array)(); + for (var i = 0; i < nodelist.length; i++) { + set.push(wrap(nodelist[i])); + } + return set; +}; + +function add2group(list) { + if (!is(list, "array")) { + list = Array.prototype.slice.call(arguments, 0); + } + var i = 0, + j = 0, + node = this.node; + while (this[i]) delete this[i++]; + for (i = 0; i < list.length; i++) { + if (list[i].type == "set") { + list[i].forEach(function (el) { + node.appendChild(el.node); + }); + } else { + node.appendChild(list[i].node); + } + } + var children = node.childNodes; + for (i = 0; i < children.length; i++) { + this[j++] = wrap(children[i]); + } + return this; +} +function Element(el) { + if (el.snap in hub) { + return hub[el.snap]; + } + var id = this.id = ID(), + svg; + try { + svg = el.ownerSVGElement; + } catch(e) {} + this.node = el; + if (svg) { + this.paper = new Paper(svg); + } + this.type = el.tagName; + this.anims = {}; + this._ = { + transform: [] + }; + el.snap = id; + hub[id] = this; + if (this.type == "g") { + this.add = add2group; + for (var method in Paper.prototype) if (Paper.prototype[has](method)) { + this[method] = Paper.prototype[method]; + } + } +} +function arrayFirstValue(arr) { + var res; + for (var i = 0, ii = arr.length; i < ii; i++) { + res = res || arr[i]; + if (res) { + return res; + } + } +} +(function (elproto) { + /*\ + * Element.attr + [ method ] + ** + * Gets or sets given attributes of the element + ** + - params (object) contains key-value pairs of attributes you want to set + * or + - param (string) name of the attribute + = (Element) the current element + * or + = (string) value of attribute + > Usage + | el.attr({ + | fill: "#fc0", + | stroke: "#000", + | strokeWidth: 2, // CamelCase... + | "fill-opacity": 0.5 // or dash-separated names + | }); + | console.log(el.attr("fill")); // #fc0 + \*/ + elproto.attr = function (params, value) { + var el = this, + node = el.node; + if (!params) { + return el; + } + if (is(params, "string")) { + if (arguments.length > 1) { + var json = {}; + json[params] = value; + params = json; + } else { + return arrayFirstValue(eve("snap.util.getattr."+params, el)); + } + } + for (var att in params) { + if (params[has](att)) { + eve("snap.util.attr." + att, el, params[att]); + } + } + 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 ] + ** + * Returns the bounding box descriptor for the given element + ** + = (object) bounding box descriptor: + o { + o cx: (number) x of the center, + o cy: (number) x of the center, + o h: (number) height, + o height: (number) height, + o path: (string) path command for the box, + o r0: (number) radius of a circle that fully encloses the box, + o r1: (number) radius of the smallest circle that can be enclosed, + o r2: (number) radius of the largest circle that can be enclosed, + o vb: (string) box as a viewbox command, + o w: (number) width, + o width: (number) width, + o x2: (number) x of the right side, + o x: (number) x of the left side, + o y2: (number) y of the bottom edge, + o y: (number) y of the top edge + o } + \*/ + elproto.getBBox = function (isWithoutTransform) { + var el = this; + if (el.type == "use") { + el = el.original; + } + if (el.removed) { + return {}; + } + var _ = el._; + if (isWithoutTransform) { + _.bboxwt = Snap.path.get[el.type] ? Snap.path.getBBox(el.realPath = Snap.path.get[el.type](el)) : Snap._.box(el.node.getBBox()); + return Snap._.box(_.bboxwt); + } else { + el.realPath = (Snap.path.get[el.type] || Snap.path.get.deflt)(el); + _.bbox = Snap.path.getBBox(Snap.path.map(el.realPath, el.matrix)); + } + return Snap._.box(_.bbox); + }; + var propString = function () { + return this.string; + }; +// SIERRA Element.transform(): seems to allow two return values, one of which (_Element_) is undefined. +// SIERRA Element.transform(): if this only accepts one argument, it's unclear how it can both _get_ and _set_ a transform. +// SIERRA Element.transform(): Unclear how Snap transform string format differs from SVG's. + /*\ + * Element.transform + [ method ] + ** + * Gets or sets transformation of the element + ** + - tstr (string) transform string in Snap or SVG format + = (Element) the current element + * or + = (object) transformation descriptor: + o { + o string (string) transform string, + o globalMatrix (Matrix) matrix of all transformations applied to element or its parents, + o localMatrix (Matrix) matrix of transformations applied only to the element, + o diffMatrix (Matrix) matrix of difference between global and local transformations, + o global (string) global transformation as string, + o local (string) local transformation as string, + o toString (function) returns `string` property + o } + \*/ + elproto.transform = function (tstr) { + var _ = this._; + if (tstr == null) { + var global = new Matrix(this.node.getCTM()), + local = extractTransform(this), + localString = local.toTransformString(), + string = Str(local) == Str(this.matrix) ? + _.transform : localString; + return { + string: string, + globalMatrix: global, + localMatrix: local, + diffMatrix: global.clone().add(local.invert()), + global: global.toTransformString(), + local: localString, + toString: propString + }; + } + if (tstr instanceof Matrix) { + // may be need to apply it directly + // TODO: investigate + tstr = tstr.toTransformString(); + } + extractTransform(this, tstr); + + if (this.node) { + if (this.type == "linearGradient" || this.type == "radialGradient") { + $(this.node, {gradientTransform: this.matrix}); + } else if (this.type == "pattern") { + $(this.node, {patternTransform: this.matrix}); + } else { + $(this.node, {transform: this.matrix}); + } + } + + return this; + }; + /*\ + * Element.parent + [ method ] + ** + * Returns the element's parent + ** + = (Element) the parent element + \*/ + elproto.parent = function () { + return wrap(this.node.parentNode); + }; + /*\ + * Element.append + [ method ] + ** + * Appends the given element to current one + ** + - el (Element|Set) element to append + = (Element) the parent element + \*/ + /*\ + * Element.add + [ method ] + ** + * See @Element.append + \*/ + elproto.append = elproto.add = function (el) { + if (el) { + if (el.type == "set") { + var it = this; + el.forEach(function (el) { + it.add(el); + }); + return this; + } + el = wrap(el); + this.node.appendChild(el.node); + el.paper = this.paper; + } + return this; + }; + /*\ + * Element.appendTo + [ method ] + ** + * Appends the current element to the given one + ** + - el (Element) parent element to append to + = (Element) the child element + \*/ + elproto.appendTo = function (el) { + if (el) { + el = wrap(el); + el.append(this); + } + return this; + }; + /*\ + * Element.prepend + [ method ] + ** + * Prepends the given element to the current one + ** + - el (Element) element to prepend + = (Element) the parent element + \*/ + elproto.prepend = function (el) { + if (el) { + el = wrap(el); + var parent = el.parent(); + this.node.insertBefore(el.node, this.node.firstChild); + this.add && this.add(); + el.paper = this.paper; + this.parent() && this.parent().add(); + parent && parent.add(); + } + return this; + }; + /*\ + * Element.prependTo + [ method ] + ** + * Prepends the current element to the given one + ** + - el (Element) parent element to prepend to + = (Element) the child element + \*/ + elproto.prependTo = function (el) { + el = wrap(el); + el.prepend(this); + return this; + }; + /*\ + * Element.before + [ method ] + ** + * Inserts given element before the current one + ** + - el (Element) element to insert + = (Element) the parent element + \*/ + elproto.before = function (el) { + if (el.type == "set") { + var it = this; + el.forEach(function (el) { + var parent = el.parent(); + it.node.parentNode.insertBefore(el.node, it.node); + parent && parent.add(); + }); + this.parent().add(); + return this; + } + el = wrap(el); + var parent = el.parent(); + this.node.parentNode.insertBefore(el.node, this.node); + this.parent() && this.parent().add(); + parent && parent.add(); + el.paper = this.paper; + return this; + }; + /*\ + * Element.after + [ method ] + ** + * Inserts given element after the current one + ** + - el (Element) element to insert + = (Element) the parent element + \*/ + elproto.after = function (el) { + el = wrap(el); + var parent = el.parent(); + if (this.node.nextSibling) { + this.node.parentNode.insertBefore(el.node, this.node.nextSibling); + } else { + this.node.parentNode.appendChild(el.node); + } + this.parent() && this.parent().add(); + parent && parent.add(); + el.paper = this.paper; + return this; + }; + /*\ + * Element.insertBefore + [ method ] + ** + * Inserts the element after the given one + ** + - el (Element) element next to whom insert to + = (Element) the parent element + \*/ + elproto.insertBefore = function (el) { + el = wrap(el); + var parent = this.parent(); + el.node.parentNode.insertBefore(this.node, el.node); + this.paper = el.paper; + parent && parent.add(); + el.parent() && el.parent().add(); + return this; + }; + /*\ + * Element.insertAfter + [ method ] + ** + * Inserts the element after the given one + ** + - el (Element) element next to whom insert to + = (Element) the parent element + \*/ + elproto.insertAfter = function (el) { + el = wrap(el); + var parent = this.parent(); + el.node.parentNode.insertBefore(this.node, el.node.nextSibling); + this.paper = el.paper; + parent && parent.add(); + el.parent() && el.parent().add(); + return this; + }; + /*\ + * Element.remove + [ method ] + ** + * Removes element from the DOM + = (Element) the detached element + \*/ + elproto.remove = function () { + var parent = this.parent(); + this.node.parentNode && this.node.parentNode.removeChild(this.node); + delete this.paper; + this.removed = true; + parent && parent.add(); + return this; + }; + /*\ + * Element.select + [ method ] + ** + * Gathers the nested @Element matching the given set of CSS selectors + ** + - query (string) CSS selector + = (Element) result of query selection + \*/ + elproto.select = function (query) { + return wrap(this.node.querySelector(query)); + }; + /*\ + * Element.selectAll + [ method ] + ** + * Gathers nested @Element objects matching the given set of CSS selectors + ** + - query (string) CSS selector + = (Set|array) result of query selection + \*/ + elproto.selectAll = function (query) { + var nodelist = this.node.querySelectorAll(query), + set = (Snap.set || Array)(); + for (var i = 0; i < nodelist.length; i++) { + set.push(wrap(nodelist[i])); + } + return set; + }; + /*\ + * Element.asPX + [ method ] + ** + * Returns given attribute of the element as a `px` value (not %, em, etc.) + ** + - attr (string) attribute name + - value (string) #optional attribute value + = (Element) result of query selection + \*/ + elproto.asPX = function (attr, value) { + if (value == null) { + value = this.attr(attr); + } + return +unit2px(this, attr, value); + }; + // SIERRA Element.use(): I suggest adding a note about how to access the original element the returned instantiates. It's a part of SVG with which ordinary web developers may be least familiar. + /*\ + * Element.use + [ method ] + ** + * Creates a `` element linked to the current element + ** + = (Element) the `` element + \*/ + elproto.use = function () { + var use, + id = this.node.id; + if (!id) { + id = this.id; + $(this.node, { + id: id + }); + } + if (this.type == "linearGradient" || this.type == "radialGradient" || + this.type == "pattern") { + use = make(this.type, this.node.parentNode); + } else { + use = make("use", this.node.parentNode); + } + $(use.node, { + "xlink:href": "#" + id + }); + use.original = this; + return use; + }; + /*\ + * Element.clone + [ method ] + ** + * Creates a clone of the element and inserts it after the element + ** + = (Element) the clone + \*/ + function fixids(el) { + var els = el.selectAll("*"), + it, + url = /^\s*url\(("|'|)(.*)\1\)\s*$/, + ids = [], + uses = {}; + function urltest(it, name) { + var val = $(it.node, name); + val = val && val.match(url); + val = val && val[2]; + if (val && val.charAt() == "#") { + val = val.substring(1); + } else { + return; + } + if (val) { + uses[val] = (uses[val] || []).concat(function (id) { + var attr = {}; + attr[name] = URL(id); + $(it.node, attr); + }); + } + } + function linktest(it) { + var val = $(it.node, "xlink:href"); + if (val && val.charAt() == "#") { + val = val.substring(1); + } else { + return; + } + if (val) { + uses[val] = (uses[val] || []).concat(function (id) { + it.attr("xlink:href", "#" + id); + }); + } + } + for (var i = 0, ii = els.length; i < ii; i++) { + it = els[i]; + urltest(it, "fill"); + urltest(it, "stroke"); + urltest(it, "filter"); + urltest(it, "mask"); + urltest(it, "clip-path"); + linktest(it); + var oldid = $(it.node, "id"); + if (oldid) { + $(it.node, {id: it.id}); + ids.push({ + old: oldid, + id: it.id + }); + } + } + for (i = 0, ii = ids.length; i < ii; i++) { + var fs = uses[ids[i].old]; + if (fs) { + for (var j = 0, jj = fs.length; j < jj; j++) { + fs[j](ids[i].id); + } + } + } + } + elproto.clone = function () { + var clone = wrap(this.node.cloneNode(true)); + if ($(clone.node, "id")) { + $(clone.node, {id: clone.id}); + } + fixids(clone); + clone.insertAfter(this); + return clone; + }; +// SIERRA Element.toDefs(): If this _moves_ an element to the region, why is the return value a _clone_? Also unclear why it's called the _relative_ section. Perhaps _shared_? + /*\ + * Element.toDefs + [ method ] + ** + * Moves element to the shared `` area + ** + = (Element) the clone + \*/ + elproto.toDefs = function () { + var defs = getSomeDefs(this); + defs.appendChild(this.node); + return this; + }; +// SIERRA Element.pattern(): x/y/width/height data types are listed as both String and Number. Is that an error, or does it mean strings are coerced? +// SIERRA Element.pattern(): clarify that x/y are offsets that e.g., may add gutters between the tiles. + /*\ + * Element.pattern + [ method ] + ** + * Creates a `` element from the current element + ** + * To create a pattern you have to specify the pattern rect: + - x (string|number) + - y (string|number) + - width (string|number) + - height (string|number) + = (Element) the `` element + * You can use pattern later on as an argument for `fill` attribute: + | var p = paper.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({ + | fill: "none", + | stroke: "#bada55", + | strokeWidth: 5 + | }).pattern(0, 0, 10, 10), + | c = paper.circle(200, 200, 100); + | c.attr({ + | fill: p + | }); + \*/ + elproto.pattern = function (x, y, width, height) { + var p = make("pattern", getSomeDefs(this)); + if (x == null) { + x = this.getBBox(); + } + if (is(x, "object") && "x" in x) { + y = x.y; + width = x.width; + height = x.height; + x = x.x; + } + $(p.node, { + x: x, + y: y, + width: width, + height: height, + patternUnits: "userSpaceOnUse", + id: p.id, + viewBox: [x, y, width, height].join(" ") + }); + p.node.appendChild(this.node); + return p; + }; +// SIERRA Element.marker(): clarify what a reference point is. E.g., helps you offset the object from its edge such as when centering it over a path. +// SIERRA Element.marker(): I suggest the method should accept default reference point values. Perhaps centered with (refX = width/2) and (refY = height/2)? Also, couldn't it assume the element's current _width_ and _height_? And please specify what _x_ and _y_ mean: offsets? If so, from where? Couldn't they also be assigned default values? + /*\ + * Element.marker + [ method ] + ** + * Creates a `` element from the current element + ** + * To create a marker you have to specify the bounding rect and reference point: + - x (number) + - y (number) + - width (number) + - height (number) + - refX (number) + - refY (number) + = (Element) the `` element + * You can specify the marker later as an argument for `marker-start`, `marker-end`, `marker-mid`, and `marker` attributes. The `marker` attribute places the marker at every point along the path, and `marker-mid` places them at every point except the start and end. + \*/ + // TODO add usage for markers + elproto.marker = function (x, y, width, height, refX, refY) { + var p = make("marker", getSomeDefs(this)); + if (x == null) { + x = this.getBBox(); + } + if (is(x, "object") && "x" in x) { + y = x.y; + width = x.width; + height = x.height; + refX = x.refX || x.cx; + refY = x.refY || x.cy; + x = x.x; + } + $(p.node, { + viewBox: [x, y, width, height].join(S), + markerWidth: width, + markerHeight: height, + orient: "auto", + refX: refX || 0, + refY: refY || 0, + id: p.id + }); + p.node.appendChild(this.node); + return p; + }; + // animation + function slice(from, to, f) { + return function (arr) { + var res = arr.slice(from, to); + if (res.length == 1) { + res = res[0]; + } + return f ? f(res) : res; + }; + } + var Animation = function (attr, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + this.attr = attr; + this.dur = ms; + easing && (this.easing = easing); + callback && (this.callback = callback); + }; + // SIERRA All object methods should feature sample code. This is just one instance. + /*\ + * Snap.animation + [ method ] + ** + * Creates an animation object + ** + - attr (object) attributes of final destination + - duration (number) duration of the animation, in milliseconds + - easing (function) #optional one of easing functions of @mina or custom one + - callback (function) #optional callback function that fires when animation ends + = (object) animation object + \*/ + Snap.animation = function (attr, ms, easing, callback) { + return new Animation(attr, ms, easing, callback); + }; + /*\ + * Element.inAnim + [ method ] + ** + * Returns a set of animations that may be able to manipulate the current element + ** + = (object) in format: + o { + o anim (object) animation object, + o curStatus (number) 0..1 — status of the animation: 0 — just started, 1 — just finished, + o status (function) gets or sets the status of the animation, + o stop (function) stops the animation + o } + \*/ + elproto.inAnim = function () { + var el = this, + res = []; + for (var id in el.anims) if (el.anims[has](id)) { + (function (a) { + res.push({ + anim: new Animation(a._attrs, a.dur, a.easing, a._callback), + curStatus: a.status(), + status: function (val) { + return a.status(val); + }, + stop: function () { + a.stop(); + } + }); + }(el.anims[id])); + } + return res; + }; + /*\ + * Snap.animate + [ method ] + ** + * Runs generic animation of one number into another with a caring function + ** + - from (number|array) number or array of numbers + - to (number|array) number or array of numbers + - setter (function) caring function that accepts one number argument + - duration (number) duration, in milliseconds + - easing (function) #optional easing function from @mina or custom + - callback (function) #optional callback function to execute when animation ends + = (object) animation object in @mina format + o { + o id (string) animation id, consider it read-only, + o duration (function) gets or sets the duration of the animation, + o easing (function) easing, + o speed (function) gets or sets the speed of the animation, + o status (function) gets or sets the status of the animation, + o stop (function) stops the animation + o } + | var rect = Snap().rect(0, 0, 10, 10); + | Snap.animate(0, 10, function (val) { + | rect.attr({ + | x: val + | }); + | }, 1000); + | // in given context is equivalent to + | rect.animate({x: 10}, 1000); + \*/ + Snap.animate = function (from, to, setter, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + var now = mina.time(), + anim = mina(from, to, now, now + ms, mina.time, setter, easing); + callback && eve.once("mina.finish." + anim.id, callback); + return anim; + }; + /*\ + * Element.stop + [ method ] + ** + * Stops all the animations for the current element + ** + = (Element) the current element + \*/ + elproto.stop = function () { + var anims = this.inAnim(); + for (var i = 0, ii = anims.length; i < ii; i++) { + anims[i].stop(); + } + return this; + }; + // SIERRA Element.animate(): For _attrs_, clarify if they represent the destination values, and if the animation executes relative to the element's current attribute values. + // SIERRA would a _custom_ animation function be an SVG keySplines value? + /*\ + * Element.animate + [ method ] + ** + * Animates the given attributes of the element + ** + - attrs (object) key-value pairs of destination attributes + - duration (number) duration of the animation in milliseconds + - easing (function) #optional easing function from @mina or custom + - callback (function) #optional callback function that executes when the animation ends + = (Element) the current element + \*/ + elproto.animate = function (attrs, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + if (attrs instanceof Animation) { + callback = attrs.callback; + easing = attrs.easing; + ms = easing.dur; + attrs = attrs.attr; + } + var fkeys = [], tkeys = [], keys = {}, from, to, f, eq, + el = this; + for (var key in attrs) if (attrs[has](key)) { + if (el.equal) { + eq = el.equal(key, Str(attrs[key])); + from = eq.from; + to = eq.to; + f = eq.f; + } else { + from = +el.attr(key); + to = +attrs[key]; + } + var len = is(from, "array") ? from.length : 1; + keys[key] = slice(fkeys.length, fkeys.length + len, f); + fkeys = fkeys.concat(from); + tkeys = tkeys.concat(to); + } + var now = mina.time(), + anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) { + var attr = {}; + for (var key in keys) if (keys[has](key)) { + attr[key] = keys[key](val); + } + el.attr(attr); + }, easing); + el.anims[anim.id] = anim; + anim._attrs = attrs; + anim._callback = callback; + eve.once("mina.finish." + anim.id, function () { + delete el.anims[anim.id]; + callback && callback.call(el); + }); + eve.once("mina.stop." + anim.id, function () { + delete el.anims[anim.id]; + }); + return el; + }; + var eldata = {}; + /*\ + * Element.data + [ method ] + ** + * Adds or retrieves given value associated with given key. (Don’t confuse + * with `data-` attributes) + * + * See also @Element.removeData + - key (string) key to store data + - value (any) #optional value to store + = (object) @Element + * or, if value is not specified: + = (any) value + > Usage + | for (var i = 0, i < 5, i++) { + | paper.circle(10 + 15 * i, 10, 10) + | .attr({fill: "#000"}) + | .data("i", i) + | .click(function () { + | alert(this.data("i")); + | }); + | } + \*/ + elproto.data = function (key, value) { + var data = eldata[this.id] = eldata[this.id] || {}; + if (arguments.length == 0){ + eve("snap.data.get." + this.id, this, data, null); + return data; + } + if (arguments.length == 1) { + if (Snap.is(key, "object")) { + for (var i in key) if (key[has](i)) { + this.data(i, key[i]); + } + return this; + } + eve("snap.data.get." + this.id, this, data[key], key); + return data[key]; + } + data[key] = value; + eve("snap.data.set." + this.id, this, value, key); + return this; + }; + /*\ + * Element.removeData + [ method ] + ** + * Removes value associated with an element by given key. + * If key is not provided, removes all the data of the element. + - key (string) #optional key + = (object) @Element + \*/ + elproto.removeData = function (key) { + if (key == null) { + eldata[this.id] = {}; + } else { + eldata[this.id] && delete eldata[this.id][key]; + } + return this; + }; + /*\ + * Element.outerSVG + [ method ] + ** + * Returns SVG code for the element, equivalent to HTML's `outerHTML`. + * + * See also @Element.innerSVG + = (string) SVG code for the element + \*/ + /*\ + * Element.toString + [ method ] + ** + * See @Element.outerSVG + \*/ + elproto.outerSVG = elproto.toString = toString(1); + /*\ + * Element.innerSVG + [ method ] + ** + * Returns SVG code for the element's contents, equivalent to HTML's `innerHTML` + = (string) SVG code for the element + \*/ + elproto.innerSVG = toString(); + function toString(type) { + return function () { + var res = type ? "<" + this.type : "", + attr = this.node.attributes, + chld = this.node.childNodes; + if (type) { + for (var i = 0, ii = attr.length; i < ii; i++) { + res += " " + attr[i].name + '="' + + attr[i].value.replace(/"/g, '\\"') + '"'; + } + } + if (chld.length) { + type && (res += ">"); + for (i = 0, ii = chld.length; i < ii; i++) { + if (chld[i].nodeType == 3) { + res += chld[i].nodeValue; + } else if (chld[i].nodeType == 1) { + res += wrap(chld[i]).toString(); + } + } + type && (res += ""); + } else { + type && (res += "/>"); + } + return res; + }; + } +}(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 ] + ** + * Parses SVG fragment and converts it into a @Fragment + ** + - svg (string) SVG string + = (Fragment) the @Fragment +\*/ +Snap.parse = function (svg) { + var f = glob.doc.createDocumentFragment(), + full = true, + div = glob.doc.createElement("div"); + svg = Str(svg); + if (!svg.match(/^\s*<\s*svg(?:\s|>)/)) { + svg = "" + svg + ""; + full = false; + } + div.innerHTML = svg; + svg = div.getElementsByTagName("svg")[0]; + if (svg) { + if (full) { + f = svg; + } else { + while (svg.firstChild) { + f.appendChild(svg.firstChild); + } + } + } + div.innerHTML = E; + return new Fragment(f); +}; +function Fragment(frag) { + this.node = frag; +} +/*\ + * Fragment.select + [ method ] + ** + * See @Element.select +\*/ +Fragment.prototype.select = Element.prototype.select; +/*\ + * Fragment.selectAll + [ method ] + ** + * See @Element.selectAll +\*/ +Fragment.prototype.selectAll = Element.prototype.selectAll; +// SIERRA Snap.fragment() could especially use a code example +/*\ + * Snap.fragment + [ method ] + ** + * Creates a DOM fragment from a given list of elements or strings + ** + - varargs (…) SVG string + = (Fragment) the @Fragment +\*/ +Snap.fragment = function () { + var args = Array.prototype.slice.call(arguments, 0), + f = glob.doc.createDocumentFragment(); + for (var i = 0, ii = args.length; i < ii; i++) { + var item = args[i]; + if (item.node && item.node.nodeType) { + f.appendChild(item.node); + } + if (item.nodeType) { + f.appendChild(item); + } + if (typeof item == "string") { + f.appendChild(Snap.parse(item).node); + } + } + return new Fragment(f); +}; + +function make(name, parent) { + var res = $(name); + parent.appendChild(res); + var el = wrap(res); + el.type = name; + return el; +} +function Paper(w, h) { + var res, + desc, + defs, + proto = Paper.prototype; + if (w && w.tagName == "svg") { + if (w.snap in hub) { + return hub[w.snap]; + } + res = new Element(w); + desc = w.getElementsByTagName("desc")[0]; + defs = w.getElementsByTagName("defs")[0]; + if (!desc) { + desc = $("desc"); + desc.appendChild(glob.doc.createTextNode("Created with Snap")); + res.node.appendChild(desc); + } + if (!defs) { + defs = $("defs"); + res.node.appendChild(defs); + } + res.defs = defs; + for (var key in proto) if (proto[has](key)) { + res[key] = proto[key]; + } + res.paper = res.root = res; + } else { + res = make("svg", glob.doc.body); + $(res.node, { + height: h, + version: 1.1, + width: w, + xmlns: xmlns + }); + } + return res; +} +function wrap(dom) { + if (!dom) { + return dom; + } + if (dom instanceof Element || dom instanceof Fragment) { + return dom; + } + if (dom.tagName == "svg") { + return new Paper(dom); + } + 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" in x) { + 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" in cx) { + 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" in cx) { + 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; + }; +// SIERRA Paper.g(): Don't understand the code comment about the order being _different._ Wouldn't it be a rect followed by a circle? + /*\ + * 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); + el.add = add2group; + for (var method in proto) if (proto[has](method)) { + el[method] = proto[method]; + } + 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.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.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])); + } + 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; + } +}; +/*\ + * 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 = 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.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 +var cssAttr = { + "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 +}; + +eve.on("snap.util.attr", function (value) { + var att = eve.nt(), + attr = {}; + att = att.substring(att.lastIndexOf(".") + 1); + attr[att] = value; + var style = att.replace(/-(\w)/gi, function (all, letter) { + return letter.toUpperCase(); + }), + css = att.replace(/[A-Z]/g, function (letter) { + return "-" + letter.toLowerCase(); + }); + if (cssAttr[has](css)) { + this.node.style[style] = value == null ? E : value; + } else { + $(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 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").split(separator); + return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]); + // TODO: investigate why I need to z-index it +})(-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; +}); +// 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 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, + body = doc.body, + docElem = doc.documentElement, + clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, + top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop, + left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft; + return { + y: top, + x: left + }; +}; +/*\ + * Snap.getElementByPoint + [ method ] + ** + * Returns you topmost element under given point. + ** + = (object) Snap element object + - x (number) x coordinate from the top left corner of the window + - y (number) y coordinate from the top left corner of the window + > Usage + | Snap.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"}); +\*/ +Snap.getElementByPoint = function (x, y) { + var paper = this, + svg = paper.canvas, + target = glob.doc.elementFromPoint(x, y); + if (glob.win.opera && target.tagName == "svg") { + var so = getOffset(target), + sr = target.createSVGRect(); + sr.x = x - so.x; + sr.y = y - so.y; + sr.width = sr.height = 1; + var hits = target.getIntersectionList(sr, null); + if (hits.length) { + target = hits[hits.length - 1]; + } + } + if (!target) { + return null; + } + return wrap(target); +}; +/*\ + * Snap.plugin + [ method ] + ** + * Let you write plugins. You pass in a function with four arguments, like this: + | Snap.plugin(function (Snap, Element, Paper, global) { + | Snap.newmethod = function () {}; + | Element.prototype.newmethod = function () {}; + | Paper.prototype.newmethod = function () {}; + | }); + * Inside the function you have access to all main objects (and their + * prototypes). This allow you to extend anything you want. + ** + - f (function) your plugin body +\*/ +Snap.plugin = function (f) { + f(Snap, Element, Paper, glob); +}; +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) { + var elproto = Element.prototype, + is = Snap.is, + clone = Snap._.clone, + has = "hasOwnProperty", + p2s = /,?([a-z]),?/gi, + toFloat = parseFloat, + math = Math, + PI = math.PI, + mmin = math.min, + mmax = math.max, + pow = math.pow, + abs = math.abs; + function paths(ps) { + var p = paths.ps = paths.ps || {}; + if (p[ps]) { + p[ps].sleep = 100; + } else { + p[ps] = { + sleep: 100 + }; + } + setTimeout(function () { + for (var key in p) if (p[has](key) && key != ps) { + p[key].sleep--; + !p[key].sleep && delete p[key]; + } + }); + return p[ps]; + } + function box(x, y, width, height) { + if (x == null) { + x = y = width = height = 0; + } + if (y == null) { + y = x.y; + width = x.width; + height = x.height; + x = x.x; + } + return { + x: x, + y: y, + width: width, + w: width, + height: height, + h: height, + x2: x + width, + y2: y + height, + cx: x + width / 2, + cy: y + height / 2, + r1: math.min(width, height) / 2, + r2: math.max(width, height) / 2, + r0: math.sqrt(width * width + height * height) / 2, + path: rectPath(x, y, width, height), + vb: [x, y, width, height].join(" ") + }; + } + function toString() { + return this.join(",").replace(p2s, "$1"); + } + function pathClone(pathArray) { + var res = clone(pathArray); + res.toString = toString; + return res; + } + function getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) { + if (length == null) { + return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y); + } else { + return findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, + getTotLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length)); + } + } + function getLengthFactory(istotal, subpath) { + function O(val) { + return +(+val).toFixed(3); + } + return Snap._.cacher(function (path, length, onlystart) { + if (path instanceof Element) { + path = path.attr("d"); + } + path = path2curve(path); + var x, y, p, l, sp = "", subpaths = {}, point, + len = 0; + for (var i = 0, ii = path.length; i < ii; i++) { + p = path[i]; + if (p[0] == "M") { + x = +p[1]; + y = +p[2]; + } else { + l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); + if (len + l > length) { + if (subpath && !subpaths.start) { + point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); + sp += [ + "C" + O(point.start.x), + O(point.start.y), + O(point.m.x), + O(point.m.y), + O(point.x), + O(point.y) + ]; + if (onlystart) {return sp;} + subpaths.start = sp; + sp = [ + "M" + O(point.x), + O(point.y) + "C" + O(point.n.x), + O(point.n.y), + O(point.end.x), + O(point.end.y), + O(p[5]), + O(p[6]) + ].join(); + len += l; + x = +p[5]; + y = +p[6]; + continue; + } + if (!istotal && !subpath) { + point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); + return point; + } + } + len += l; + x = +p[5]; + y = +p[6]; + } + sp += p.shift() + p; + } + subpaths.end = sp; + point = istotal ? len : subpath ? subpaths : findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1); + return point; + }, null, Snap._.clone); + } + var getTotalLength = getLengthFactory(1), + getPointAtLength = getLengthFactory(), + getSubpathsAtLength = getLengthFactory(0, 1); + function findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { + var t1 = 1 - t, + t13 = pow(t1, 3), + t12 = pow(t1, 2), + t2 = t * t, + t3 = t2 * t, + x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x, + y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y, + mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x), + my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y), + nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x), + ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y), + ax = t1 * p1x + t * c1x, + ay = t1 * p1y + t * c1y, + cx = t1 * c2x + t * p2x, + cy = t1 * c2y + t * p2y, + alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI); + // (mx > nx || my < ny) && (alpha += 180); + return { + x: x, + y: y, + m: {x: mx, y: my}, + n: {x: nx, y: ny}, + start: {x: ax, y: ay}, + end: {x: cx, y: cy}, + alpha: alpha + }; + } + function bezierBBox(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { + if (!Snap.is(p1x, "array")) { + p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]; + } + var bbox = curveDim.apply(null, p1x); + return box( + bbox.min.x, + bbox.min.y, + bbox.max.x - bbox.min.x, + bbox.max.y - bbox.min.y + ); + } + function isPointInsideBBox(bbox, x, y) { + return x >= bbox.x && + x <= bbox.x + bbox.width && + y >= bbox.y && + y <= bbox.y + bbox.height; + } + function isBBoxIntersect(bbox1, bbox2) { + bbox1 = box(bbox1); + bbox2 = box(bbox2); + return isPointInsideBBox(bbox2, bbox1.x, bbox1.y) + || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y) + || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2) + || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2) + || isPointInsideBBox(bbox1, bbox2.x, bbox2.y) + || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y) + || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2) + || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2) + || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x + || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x) + && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y + || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y); + } + function base3(t, p1, p2, p3, p4) { + var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4, + t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; + return t * t2 - 3 * p1 + 3 * p2; + } + function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) { + if (z == null) { + z = 1; + } + z = z > 1 ? 1 : z < 0 ? 0 : z; + var z2 = z / 2, + n = 12, + Tvalues = [-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816], + Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472], + sum = 0; + for (var i = 0; i < n; i++) { + var ct = z2 * Tvalues[i] + z2, + xbase = base3(ct, x1, x2, x3, x4), + ybase = base3(ct, y1, y2, y3, y4), + comb = xbase * xbase + ybase * ybase; + sum += Cvalues[i] * math.sqrt(comb); + } + return z2 * sum; + } + function getTotLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) { + if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) { + return; + } + var t = 1, + step = t / 2, + t2 = t - step, + l, + e = .01; + l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2); + while (abs(l - ll) > e) { + step /= 2; + t2 += (l < ll ? 1 : -1) * step; + l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2); + } + return t2; + } + function intersect(x1, y1, x2, y2, x3, y3, x4, y4) { + if ( + mmax(x1, x2) < mmin(x3, x4) || + mmin(x1, x2) > mmax(x3, x4) || + mmax(y1, y2) < mmin(y3, y4) || + mmin(y1, y2) > mmax(y3, y4) + ) { + return; + } + var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), + ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), + denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); + + if (!denominator) { + return; + } + var px = nx / denominator, + py = ny / denominator, + px2 = +px.toFixed(2), + py2 = +py.toFixed(2); + if ( + px2 < +mmin(x1, x2).toFixed(2) || + px2 > +mmax(x1, x2).toFixed(2) || + px2 < +mmin(x3, x4).toFixed(2) || + px2 > +mmax(x3, x4).toFixed(2) || + py2 < +mmin(y1, y2).toFixed(2) || + py2 > +mmax(y1, y2).toFixed(2) || + py2 < +mmin(y3, y4).toFixed(2) || + py2 > +mmax(y3, y4).toFixed(2) + ) { + return; + } + return {x: px, y: py}; + } + function inter(bez1, bez2) { + return interHelper(bez1, bez2); + } + function interCount(bez1, bez2) { + return interHelper(bez1, bez2, 1); + } + function interHelper(bez1, bez2, justCount) { + var bbox1 = bezierBBox(bez1), + bbox2 = bezierBBox(bez2); + if (!isBBoxIntersect(bbox1, bbox2)) { + return justCount ? 0 : []; + } + var l1 = bezlen.apply(0, bez1), + l2 = bezlen.apply(0, bez2), + n1 = ~~(l1 / 5), + n2 = ~~(l2 / 5), + dots1 = [], + dots2 = [], + xy = {}, + res = justCount ? 0 : []; + for (var i = 0; i < n1 + 1; i++) { + var p = findDotsAtSegment.apply(0, bez1.concat(i / n1)); + dots1.push({x: p.x, y: p.y, t: i / n1}); + } + for (i = 0; i < n2 + 1; i++) { + p = findDotsAtSegment.apply(0, bez2.concat(i / n2)); + dots2.push({x: p.x, y: p.y, t: i / n2}); + } + for (i = 0; i < n1; i++) { + for (var j = 0; j < n2; j++) { + var di = dots1[i], + di1 = dots1[i + 1], + dj = dots2[j], + dj1 = dots2[j + 1], + ci = abs(di1.x - di.x) < .001 ? "y" : "x", + cj = abs(dj1.x - dj.x) < .001 ? "y" : "x", + is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y); + if (is) { + if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) { + continue; + } + xy[is.x.toFixed(4)] = is.y.toFixed(4); + var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t), + t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t); + if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) { + if (justCount) { + res++; + } else { + res.push({ + x: is.x, + y: is.y, + t1: t1, + t2: t2 + }); + } + } + } + } + } + return res; + } + function pathIntersection(path1, path2) { + return interPathHelper(path1, path2); + } + function pathIntersectionNumber(path1, path2) { + return interPathHelper(path1, path2, 1); + } + function interPathHelper(path1, path2, justCount) { + path1 = path2curve(path1); + path2 = path2curve(path2); + var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2, + res = justCount ? 0 : []; + for (var i = 0, ii = path1.length; i < ii; i++) { + var pi = path1[i]; + if (pi[0] == "M") { + x1 = x1m = pi[1]; + y1 = y1m = pi[2]; + } else { + if (pi[0] == "C") { + bez1 = [x1, y1].concat(pi.slice(1)); + x1 = bez1[6]; + y1 = bez1[7]; + } else { + bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m]; + x1 = x1m; + y1 = y1m; + } + for (var j = 0, jj = path2.length; j < jj; j++) { + var pj = path2[j]; + if (pj[0] == "M") { + x2 = x2m = pj[1]; + y2 = y2m = pj[2]; + } else { + if (pj[0] == "C") { + bez2 = [x2, y2].concat(pj.slice(1)); + x2 = bez2[6]; + y2 = bez2[7]; + } else { + bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m]; + x2 = x2m; + y2 = y2m; + } + var intr = interHelper(bez1, bez2, justCount); + if (justCount) { + res += intr; + } else { + for (var k = 0, kk = intr.length; k < kk; k++) { + intr[k].segment1 = i; + intr[k].segment2 = j; + intr[k].bez1 = bez1; + intr[k].bez2 = bez2; + } + res = res.concat(intr); + } + } + } + } + } + return res; + } + function isPointInsidePath(path, x, y) { + var bbox = pathBBox(path); + return isPointInsideBBox(bbox, x, y) && + interPathHelper(path, [["M", x, y], ["H", bbox.x2 + 10]], 1) % 2 == 1; + } + function pathBBox(path) { + var pth = paths(path); + if (pth.bbox) { + return clone(pth.bbox); + } + if (!path) { + return box(); + } + path = path2curve(path); + var x = 0, + y = 0, + X = [], + Y = [], + p; + for (var i = 0, ii = path.length; i < ii; i++) { + p = path[i]; + if (p[0] == "M") { + x = p[1]; + y = p[2]; + X.push(x); + Y.push(y); + } else { + var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); + X = X.concat(dim.min.x, dim.max.x); + Y = Y.concat(dim.min.y, dim.max.y); + x = p[5]; + y = p[6]; + } + } + var xmin = mmin.apply(0, X), + ymin = mmin.apply(0, Y), + xmax = mmax.apply(0, X), + ymax = mmax.apply(0, Y), + bb = box(xmin, ymin, xmax - xmin, ymax - ymin); + pth.bbox = clone(bb); + return bb; + } + function rectPath(x, y, w, h, r) { + if (r) { + return [ + ["M", x + r, y], + ["l", w - r * 2, 0], + ["a", r, r, 0, 0, 1, r, r], + ["l", 0, h - r * 2], + ["a", r, r, 0, 0, 1, -r, r], + ["l", r * 2 - w, 0], + ["a", r, r, 0, 0, 1, -r, -r], + ["l", 0, r * 2 - h], + ["a", r, r, 0, 0, 1, r, -r], + ["z"] + ]; + } + var res = [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]]; + res.toString = toString; + return res; + } + function ellipsePath(x, y, rx, ry, a) { + if (a == null && ry == null) { + ry = rx; + } + if (a != null) { + var rad = Math.PI / 180, + x1 = x + rx * Math.cos(-ry * rad), + x2 = x + rx * Math.cos(-a * rad), + y1 = y + rx * Math.sin(-ry * rad), + y2 = y + rx * Math.sin(-a * rad), + res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]]; + } else { + res = [ + ["M", x, y], + ["m", 0, -ry], + ["a", rx, ry, 0, 1, 1, 0, 2 * ry], + ["a", rx, ry, 0, 1, 1, 0, -2 * ry], + ["z"] + ]; + } + res.toString = toString; + return res; + } + var unit2px = Snap._unit2px, + getPath = { + path: function (el) { + return el.attr("path"); + }, + circle: function (el) { + var attr = unit2px(el); + return ellipsePath(attr.cx, attr.cy, attr.r); + }, + ellipse: function (el) { + var attr = unit2px(el); + return ellipsePath(attr.cx, attr.cy, attr.rx, attr.ry); + }, + rect: function (el) { + var attr = unit2px(el); + return rectPath(attr.x, attr.y, attr.width, attr.height, attr.rx, attr.ry); + }, + image: function (el) { + var attr = unit2px(el); + return rectPath(attr.x, attr.y, attr.width, attr.height); + }, + text: function (el) { + var bbox = el.node.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, + g: function (el) { + var bbox = el.node.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, + symbol: function (el) { + var bbox = el.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, + line: function (el) { + return "M" + [el.attr("x1"), el.attr("y1"), el.attr("x2"), el.attr("y2")]; + }, + polyline: function (el) { + return "M" + el.attr("points"); + }, + polygon: function (el) { + return "M" + el.attr("points") + "z"; + }, + svg: function (el) { + var bbox = el.node.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, + deflt: function (el) { + var bbox = el.node.getBBox(); + return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + } + }; + function pathToRelative(pathArray) { + var pth = paths(pathArray), + lowerCase = String.prototype.toLowerCase; + if (pth.rel) { + return pathClone(pth.rel); + } + if (!Snap.is(pathArray, "array") || !Snap.is(pathArray && pathArray[0], "array")) { + pathArray = Snap.parsePathString(pathArray); + } + var res = [], + x = 0, + y = 0, + mx = 0, + my = 0, + start = 0; + if (pathArray[0][0] == "M") { + x = pathArray[0][1]; + y = pathArray[0][2]; + mx = x; + my = y; + start++; + res.push(["M", x, y]); + } + for (var i = start, ii = pathArray.length; i < ii; i++) { + var r = res[i] = [], + pa = pathArray[i]; + if (pa[0] != lowerCase.call(pa[0])) { + r[0] = lowerCase.call(pa[0]); + switch (r[0]) { + case "a": + r[1] = pa[1]; + r[2] = pa[2]; + r[3] = pa[3]; + r[4] = pa[4]; + r[5] = pa[5]; + r[6] = +(pa[6] - x).toFixed(3); + r[7] = +(pa[7] - y).toFixed(3); + break; + case "v": + r[1] = +(pa[1] - y).toFixed(3); + break; + case "m": + mx = pa[1]; + my = pa[2]; + default: + for (var j = 1, jj = pa.length; j < jj; j++) { + r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3); + } + } + } else { + r = res[i] = []; + if (pa[0] == "m") { + mx = pa[1] + x; + my = pa[2] + y; + } + for (var k = 0, kk = pa.length; k < kk; k++) { + res[i][k] = pa[k]; + } + } + var len = res[i].length; + switch (res[i][0]) { + case "z": + x = mx; + y = my; + break; + case "h": + x += +res[i][len - 1]; + break; + case "v": + y += +res[i][len - 1]; + break; + default: + x += +res[i][len - 2]; + y += +res[i][len - 1]; + } + } + res.toString = toString; + pth.rel = pathClone(res); + return res; + } + function pathToAbsolute(pathArray) { + var pth = paths(pathArray); + if (pth.abs) { + return pathClone(pth.abs); + } + if (!is(pathArray, "array") || !is(pathArray && pathArray[0], "array")) { // rough assumption + pathArray = Snap.parsePathString(pathArray); + } + if (!pathArray || !pathArray.length) { + return [["M", 0, 0]]; + } + var res = [], + x = 0, + y = 0, + mx = 0, + my = 0, + start = 0, + pa0; + if (pathArray[0][0] == "M") { + x = +pathArray[0][1]; + y = +pathArray[0][2]; + mx = x; + my = y; + start++; + res[0] = ["M", x, y]; + } + var crz = pathArray.length == 3 && + pathArray[0][0] == "M" && + pathArray[1][0].toUpperCase() == "R" && + pathArray[2][0].toUpperCase() == "Z"; + for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) { + res.push(r = []); + pa = pathArray[i]; + pa0 = pa[0]; + if (pa0 != pa0.toUpperCase()) { + r[0] = pa0.toUpperCase(); + switch (r[0]) { + case "A": + r[1] = pa[1]; + r[2] = pa[2]; + r[3] = pa[3]; + r[4] = pa[4]; + r[5] = pa[5]; + r[6] = +(pa[6] + x); + r[7] = +(pa[7] + y); + break; + case "V": + r[1] = +pa[1] + y; + break; + case "H": + r[1] = +pa[1] + x; + break; + case "R": + var dots = [x, y].concat(pa.slice(1)); + for (var j = 2, jj = dots.length; j < jj; j++) { + dots[j] = +dots[j] + x; + dots[++j] = +dots[j] + y; + } + res.pop(); + res = res.concat(catmullRom2bezier(dots, crz)); + break; + case "O": + res.pop(); + dots = ellipsePath(x, y, pa[1], pa[2]); + dots.push(dots[0]); + res = res.concat(dots); + break; + case "U": + res.pop(); + res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3])); + r = ["U"].concat(res[res.length - 1].slice(-2)); + break; + case "M": + mx = +pa[1] + x; + my = +pa[2] + y; + default: + for (j = 1, jj = pa.length; j < jj; j++) { + r[j] = +pa[j] + ((j % 2) ? x : y); + } + } + } else if (pa0 == "R") { + dots = [x, y].concat(pa.slice(1)); + res.pop(); + res = res.concat(catmullRom2bezier(dots, crz)); + r = ["R"].concat(pa.slice(-2)); + } else if (pa0 == "O") { + res.pop(); + dots = ellipsePath(x, y, pa[1], pa[2]); + dots.push(dots[0]); + res = res.concat(dots); + } else if (pa0 == "U") { + res.pop(); + res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3])); + r = ["U"].concat(res[res.length - 1].slice(-2)); + } else { + for (var k = 0, kk = pa.length; k < kk; k++) { + r[k] = pa[k]; + } + } + pa0 = pa0.toUpperCase(); + if (pa0 != "O") { + switch (r[0]) { + case "Z": + x = mx; + y = my; + break; + case "H": + x = r[1]; + break; + case "V": + y = r[1]; + break; + case "M": + mx = r[r.length - 2]; + my = r[r.length - 1]; + default: + x = r[r.length - 2]; + y = r[r.length - 1]; + } + } + } + res.toString = toString; + pth.abs = pathClone(res); + return res; + } + function l2c(x1, y1, x2, y2) { + return [x1, y1, x2, y2, x2, y2]; + } + function q2c(x1, y1, ax, ay, x2, y2) { + var _13 = 1 / 3, + _23 = 2 / 3; + return [ + _13 * x1 + _23 * ax, + _13 * y1 + _23 * ay, + _13 * x2 + _23 * ax, + _13 * y2 + _23 * ay, + x2, + y2 + ]; + } + function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { + // for more information of where this math came from visit: + // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes + var _120 = PI * 120 / 180, + rad = PI / 180 * (+angle || 0), + res = [], + xy, + rotate = Snap._.cacher(function (x, y, rad) { + var X = x * math.cos(rad) - y * math.sin(rad), + Y = x * math.sin(rad) + y * math.cos(rad); + return {x: X, y: Y}; + }); + if (!recursive) { + xy = rotate(x1, y1, -rad); + x1 = xy.x; + y1 = xy.y; + xy = rotate(x2, y2, -rad); + x2 = xy.x; + y2 = xy.y; + var cos = math.cos(PI / 180 * angle), + sin = math.sin(PI / 180 * angle), + x = (x1 - x2) / 2, + y = (y1 - y2) / 2; + var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); + if (h > 1) { + h = math.sqrt(h); + rx = h * rx; + ry = h * ry; + } + var rx2 = rx * rx, + ry2 = ry * ry, + k = (large_arc_flag == sweep_flag ? -1 : 1) * + math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))), + cx = k * rx * y / ry + (x1 + x2) / 2, + cy = k * -ry * x / rx + (y1 + y2) / 2, + f1 = math.asin(((y1 - cy) / ry).toFixed(9)), + f2 = math.asin(((y2 - cy) / ry).toFixed(9)); + + f1 = x1 < cx ? PI - f1 : f1; + f2 = x2 < cx ? PI - f2 : f2; + f1 < 0 && (f1 = PI * 2 + f1); + f2 < 0 && (f2 = PI * 2 + f2); + if (sweep_flag && f1 > f2) { + f1 = f1 - PI * 2; + } + if (!sweep_flag && f2 > f1) { + f2 = f2 - PI * 2; + } + } else { + f1 = recursive[0]; + f2 = recursive[1]; + cx = recursive[2]; + cy = recursive[3]; + } + var df = f2 - f1; + if (abs(df) > _120) { + var f2old = f2, + x2old = x2, + y2old = y2; + f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); + x2 = cx + rx * math.cos(f2); + y2 = cy + ry * math.sin(f2); + res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); + } + df = f2 - f1; + var c1 = math.cos(f1), + s1 = math.sin(f1), + c2 = math.cos(f2), + s2 = math.sin(f2), + t = math.tan(df / 4), + hx = 4 / 3 * rx * t, + hy = 4 / 3 * ry * t, + m1 = [x1, y1], + m2 = [x1 + hx * s1, y1 - hy * c1], + m3 = [x2 + hx * s2, y2 - hy * c2], + m4 = [x2, y2]; + m2[0] = 2 * m1[0] - m2[0]; + m2[1] = 2 * m1[1] - m2[1]; + if (recursive) { + return [m2, m3, m4].concat(res); + } else { + res = [m2, m3, m4].concat(res).join().split(","); + var newres = []; + for (var i = 0, ii = res.length; i < ii; i++) { + newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; + } + return newres; + } + } + function findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { + var t1 = 1 - t; + return { + x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x, + y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y + }; + } + function curveDim(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { + var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x), + b = 2 * (c1x - p1x) - 2 * (c2x - c1x), + c = p1x - c1x, + t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a, + t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a, + y = [p1y, p2y], + x = [p1x, p2x], + dot; + abs(t1) > "1e12" && (t1 = .5); + abs(t2) > "1e12" && (t2 = .5); + if (t1 > 0 && t1 < 1) { + dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); + x.push(dot.x); + y.push(dot.y); + } + if (t2 > 0 && t2 < 1) { + dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); + x.push(dot.x); + y.push(dot.y); + } + a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y); + b = 2 * (c1y - p1y) - 2 * (c2y - c1y); + c = p1y - c1y; + t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a; + t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a; + abs(t1) > "1e12" && (t1 = .5); + abs(t2) > "1e12" && (t2 = .5); + if (t1 > 0 && t1 < 1) { + dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); + x.push(dot.x); + y.push(dot.y); + } + if (t2 > 0 && t2 < 1) { + dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); + x.push(dot.x); + y.push(dot.y); + } + return { + min: {x: mmin.apply(0, x), y: mmin.apply(0, y)}, + max: {x: mmax.apply(0, x), y: mmax.apply(0, y)} + }; + } + function path2curve(path, path2) { + var pth = !path2 && paths(path); + if (!path2 && pth.curve) { + return pathClone(pth.curve); + } + var p = pathToAbsolute(path), + p2 = path2 && pathToAbsolute(path2), + attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, + attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, + processPath = function (path, d) { + var nx, ny; + if (!path) { + return ["C", d.x, d.y, d.x, d.y, d.x, d.y]; + } + !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null); + switch (path[0]) { + case "M": + d.X = path[1]; + d.Y = path[2]; + break; + case "A": + path = ["C"].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1)))); + break; + case "S": + nx = d.x + (d.x - (d.bx || d.x)); + ny = d.y + (d.y - (d.by || d.y)); + path = ["C", nx, ny].concat(path.slice(1)); + break; + case "T": + d.qx = d.x + (d.x - (d.qx || d.x)); + d.qy = d.y + (d.y - (d.qy || d.y)); + path = ["C"].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])); + break; + case "Q": + d.qx = path[1]; + d.qy = path[2]; + path = ["C"].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4])); + break; + case "L": + path = ["C"].concat(l2c(d.x, d.y, path[1], path[2])); + break; + case "H": + path = ["C"].concat(l2c(d.x, d.y, path[1], d.y)); + break; + case "V": + path = ["C"].concat(l2c(d.x, d.y, d.x, path[1])); + break; + case "Z": + path = ["C"].concat(l2c(d.x, d.y, d.X, d.Y)); + break; + } + return path; + }, + fixArc = function (pp, i) { + if (pp[i].length > 7) { + pp[i].shift(); + var pi = pp[i]; + while (pi.length) { + pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6))); + } + pp.splice(i, 1); + ii = mmax(p.length, p2 && p2.length || 0); + } + }, + fixM = function (path1, path2, a1, a2, i) { + if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") { + path2.splice(i, 0, ["M", a2.x, a2.y]); + a1.bx = 0; + a1.by = 0; + a1.x = path1[i][1]; + a1.y = path1[i][2]; + ii = mmax(p.length, p2 && p2.length || 0); + } + }; + for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) { + p[i] = processPath(p[i], attrs); + fixArc(p, i); + p2 && (p2[i] = processPath(p2[i], attrs2)); + p2 && fixArc(p2, i); + fixM(p, p2, attrs, attrs2, i); + fixM(p2, p, attrs2, attrs, i); + var seg = p[i], + seg2 = p2 && p2[i], + seglen = seg.length, + seg2len = p2 && seg2.length; + attrs.x = seg[seglen - 2]; + attrs.y = seg[seglen - 1]; + attrs.bx = toFloat(seg[seglen - 4]) || attrs.x; + attrs.by = toFloat(seg[seglen - 3]) || attrs.y; + attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x); + attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y); + attrs2.x = p2 && seg2[seg2len - 2]; + attrs2.y = p2 && seg2[seg2len - 1]; + } + if (!p2) { + pth.curve = pathClone(p); + } + return p2 ? [p, p2] : p; + } + function mapPath(path, matrix) { + if (!matrix) { + return path; + } + var x, y, i, j, ii, jj, pathi; + path = path2curve(path); + for (i = 0, ii = path.length; i < ii; i++) { + pathi = path[i]; + for (j = 1, jj = pathi.length; j < jj; j += 2) { + x = matrix.x(pathi[j], pathi[j + 1]); + y = matrix.y(pathi[j], pathi[j + 1]); + pathi[j] = x; + pathi[j + 1] = y; + } + } + return path; + } + + // http://schepers.cc/getting-to-the-point + function catmullRom2bezier(crp, z) { + var d = []; + for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { + var p = [ + {x: +crp[i - 2], y: +crp[i - 1]}, + {x: +crp[i], y: +crp[i + 1]}, + {x: +crp[i + 2], y: +crp[i + 3]}, + {x: +crp[i + 4], y: +crp[i + 5]} + ]; + if (z) { + if (!i) { + p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]}; + } else if (iLen - 4 == i) { + p[3] = {x: +crp[0], y: +crp[1]}; + } else if (iLen - 2 == i) { + p[2] = {x: +crp[0], y: +crp[1]}; + p[3] = {x: +crp[2], y: +crp[3]}; + } + } else { + if (iLen - 4 == i) { + p[3] = p[2]; + } else if (!i) { + p[0] = {x: +crp[i], y: +crp[i + 1]}; + } + } + d.push(["C", + (-p[0].x + 6 * p[1].x + p[2].x) / 6, + (-p[0].y + 6 * p[1].y + p[2].y) / 6, + (p[1].x + 6 * p[2].x - p[3].x) / 6, + (p[1].y + 6*p[2].y - p[3].y) / 6, + p[2].x, + p[2].y + ]); + } + + return d; + } + + // export + Snap.path = paths; + + /*\ + * Snap.path.getTotalLength + [ method ] + ** + * Returns the length of the given path in pixels + ** + - path (string) SVG path string + ** + = (number) length + \*/ + Snap.path.getTotalLength = getTotalLength; + /*\ + * Snap.path.getPointAtLength + [ method ] + ** + * Returns the coordinates of the point located at the given length along the given path + ** + - path (string) SVG path string + - length (number) length, in pixels, from the start of the path, excluding non-rendering jumps + ** + = (object) representation of the point: + o { + o x: (number) x coordinate, + o y: (number) y coordinate, + o alpha: (number) angle of derivative + o } + \*/ + Snap.path.getPointAtLength = getPointAtLength; + /*\ + * Snap.path.getSubpath + [ method ] + ** + * Returns the subpath of a given path between given start and end lengths + ** + - path (string) SVG path string + - from (number) length, in pixels, from the start of the path to the start of the segment + - to (number) length, in pixels, from the start of the path to the end of the segment + ** + = (string) path string definition for the segment + \*/ + Snap.path.getSubpath = function (path, from, to) { + if (this.getTotalLength(path) - to < 1e-6) { + return getSubpathsAtLength(path, from).end; + } + var a = getSubpathsAtLength(path, to, 1); + return from ? getSubpathsAtLength(a, from).end : a; + }; + /*\ + * Element.getTotalLength + [ method ] + ** + * Returns the length of the path in pixels (only works for `path` elements) + = (number) length + \*/ + elproto.getTotalLength = function () { + if (this.node.getTotalLength) { + return this.node.getTotalLength(); + } + }; + // SIERRA Element.getPointAtLength()/Element.getTotalLength(): If a is broken into different segments, is the jump distance to the new coordinates set by the _M_ or _m_ commands calculated as part of the path's total length? + /*\ + * Element.getPointAtLength + [ method ] + ** + * Returns coordinates of the point located at the given length on the given path (only works for `path` elements) + ** + - length (number) length, in pixels, from the start of the path, excluding non-rendering jumps + ** + = (object) representation of the point: + o { + o x: (number) x coordinate, + o y: (number) y coordinate, + o alpha: (number) angle of derivative + o } + \*/ + elproto.getPointAtLength = function (length) { + return getPointAtLength(this.attr("d"), length); + }; + // SIERRA Element.getSubpath(): Similar to the problem for Element.getPointAtLength(). Unclear how this would work for a segmented path. Overall, the concept of _subpath_ and what I'm calling a _segment_ (series of non-_M_ or _Z_ commands) is unclear. + /*\ + * Element.getSubpath + [ method ] + ** + * Returns subpath of a given element from given start and end lengths (only works for `path` elements) + ** + - from (number) length, in pixels, from the start of the path to the start of the segment + - to (number) length, in pixels, from the start of the path to the end of the segment + ** + = (string) path string definition for the segment + \*/ + elproto.getSubpath = function (from, to) { + return Snap.path.getSubpath(this.attr("d"), from, to); + }; + Snap._.box = box; + /*\ + * Snap.path.findDotsAtSegment + [ method ] + ** + * Utility method + ** + * Finds dot coordinates on the given cubic beziér curve at the given t + - p1x (number) x of the first point of the curve + - p1y (number) y of the first point of the curve + - c1x (number) x of the first anchor of the curve + - c1y (number) y of the first anchor of the curve + - c2x (number) x of the second anchor of the curve + - c2y (number) y of the second anchor of the curve + - p2x (number) x of the second point of the curve + - p2y (number) y of the second point of the curve + - t (number) position on the curve (0..1) + = (object) point information in format: + o { + o x: (number) x coordinate of the point, + o y: (number) y coordinate of the point, + o m: { + o x: (number) x coordinate of the left anchor, + o y: (number) y coordinate of the left anchor + o }, + o n: { + o x: (number) x coordinate of the right anchor, + o y: (number) y coordinate of the right anchor + o }, + o start: { + o x: (number) x coordinate of the start of the curve, + o y: (number) y coordinate of the start of the curve + o }, + o end: { + o x: (number) x coordinate of the end of the curve, + o y: (number) y coordinate of the end of the curve + o }, + o alpha: (number) angle of the curve derivative at the point + o } + \*/ + Snap.path.findDotsAtSegment = findDotsAtSegment; + /*\ + * Snap.path.bezierBBox + [ method ] + ** + * Utility method + ** + * Returns the bounding box of a given cubic beziér curve + - p1x (number) x of the first point of the curve + - p1y (number) y of the first point of the curve + - c1x (number) x of the first anchor of the curve + - c1y (number) y of the first anchor of the curve + - c2x (number) x of the second anchor of the curve + - c2y (number) y of the second anchor of the curve + - p2x (number) x of the second point of the curve + - p2y (number) y of the second point of the curve + * or + - bez (array) array of six points for beziér curve + = (object) bounding box + o { + o x: (number) x coordinate of the left top point of the box, + o y: (number) y coordinate of the left top point of the box, + o x2: (number) x coordinate of the right bottom point of the box, + o y2: (number) y coordinate of the right bottom point of the box, + o width: (number) width of the box, + o height: (number) height of the box + o } + \*/ + Snap.path.bezierBBox = bezierBBox; + /*\ + * Snap.path.isPointInsideBBox + [ method ] + ** + * Utility method + ** + * Returns `true` if given point is inside bounding box + - bbox (string) bounding box + - x (string) x coordinate of the point + - y (string) y coordinate of the point + = (boolean) `true` if point is inside + \*/ + Snap.path.isPointInsideBBox = isPointInsideBBox; + /*\ + * Snap.path.isBBoxIntersect + [ method ] + ** + * Utility method + ** + * Returns `true` if two bounding boxes intersect + - bbox1 (string) first bounding box + - bbox2 (string) second bounding box + = (boolean) `true` if bounding boxes intersect + \*/ + Snap.path.isBBoxIntersect = isBBoxIntersect; + /*\ + * Snap.path.intersection + [ method ] + ** + * Utility method + ** + * Finds intersections of two paths + - path1 (string) path string + - path2 (string) path string + = (array) dots of intersection + o [ + o { + o x: (number) x coordinate of the point, + o y: (number) y coordinate of the point, + o t1: (number) t value for segment of path1, + o t2: (number) t value for segment of path2, + o segment1: (number) order number for segment of path1, + o segment2: (number) order number for segment of path2, + o bez1: (array) eight coordinates representing beziér curve for the segment of path1, + o bez2: (array) eight coordinates representing beziér curve for the segment of path2 + o } + o ] + \*/ + Snap.path.intersection = pathIntersection; + Snap.path.intersectionNumber = pathIntersectionNumber; + /*\ + * Snap.path.isPointInside + [ method ] + ** + * Utility method + ** + * Returns `true` if given point is inside a given closed path. + * + * Note: fill mode doesn’t affect the result of this method. + - path (string) path string + - x (number) x of the point + - y (number) y of the point + = (boolean) `true` if point is inside the path + \*/ + Snap.path.isPointInside = isPointInsidePath; + /*\ + * Snap.path.getBBox + [ method ] + ** + * Utility method + ** + * Returns the bounding box of a given path + - path (string) path string + = (object) bounding box + o { + o x: (number) x coordinate of the left top point of the box, + o y: (number) y coordinate of the left top point of the box, + o x2: (number) x coordinate of the right bottom point of the box, + o y2: (number) y coordinate of the right bottom point of the box, + o width: (number) width of the box, + o height: (number) height of the box + o } + \*/ + Snap.path.getBBox = pathBBox; + Snap.path.get = getPath; + /*\ + * Snap.path.toRelative + [ method ] + ** + * Utility method + ** + * Converts path coordinates into relative values + - path (string) path string + = (array) path string + \*/ + Snap.path.toRelative = pathToRelative; + /*\ + * Snap.path.toAbsolute + [ method ] + ** + * Utility method + ** + * Converts path coordinates into absolute values + - path (string) path string + = (array) path string + \*/ + Snap.path.toAbsolute = pathToAbsolute; + /*\ + * Snap.path.toCubic + [ method ] + ** + * Utility method + ** + * Converts path to a new path where all segments are cubic beziér curves + - pathString (string|array) path string or array of segments + = (array) array of segments + \*/ + Snap.path.toCubic = path2curve; + /*\ + * Snap.path.map + [ method ] + ** + * Transform the path string with the given matrix + - path (string) path string + - matrix (object) see @Matrix + = (string) transformed path string + \*/ + Snap.path.map = mapPath; + Snap.path.toString = toString; + Snap.path.clone = pathClone; +}); +// 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) { + var mmax = Math.max, + mmin = Math.min; + + // Set + var Set = function (items) { + this.items = []; + this.length = 0; + this.type = "set"; + if (items) { + for (var i = 0, ii = items.length; i < ii; i++) { + if (items[i]) { + this[this.items.length] = this.items[this.items.length] = items[i]; + this.length++; + } + } + } + }, + setproto = Set.prototype; + /*\ + * Set.push + [ method ] + ** + * Adds each argument to the current set + = (object) original element + \*/ + setproto.push = function () { + var item, + len; + for (var i = 0, ii = arguments.length; i < ii; i++) { + item = arguments[i]; + if (item) { + len = this.items.length; + this[len] = this.items[len] = item; + this.length++; + } + } + return this; + }; + /*\ + * Set.pop + [ method ] + ** + * Removes last element and returns it + = (object) element + \*/ + setproto.pop = function () { + this.length && delete this[this.length--]; + return this.items.pop(); + }; + /*\ + * Set.forEach + [ method ] + ** + * Executes given function for each element in the set + * + * If the function returns `false`, the loop stops running. + ** + - callback (function) function to run + - thisArg (object) context object for the callback + = (object) Set object + \*/ + setproto.forEach = function (callback, thisArg) { + for (var i = 0, ii = this.items.length; i < ii; i++) { + if (callback.call(thisArg, this.items[i], i) === false) { + return this; + } + } + return this; + }; + setproto.remove = function () { + while (this.length) { + this.pop().remove(); + } + return this; + }; + setproto.attr = function (value) { + for (var i = 0, ii = this.items.length; i < ii; i++) { + this.items[i].attr(value); + } + return this; + }; + /*\ + * Set.clear + [ method ] + ** + * Removes all elements from the set + \*/ + setproto.clear = function () { + while (this.length) { + this.pop(); + } + }; + /*\ + * Set.splice + [ method ] + ** + * Removes range of elements from the set + ** + - index (number) position of the deletion + - count (number) number of element to remove + - insertion… (object) #optional elements to insert + = (object) set elements that were deleted + \*/ + setproto.splice = function (index, count, insertion) { + index = index < 0 ? mmax(this.length + index, 0) : index; + count = mmax(0, mmin(this.length - index, count)); + var tail = [], + todel = [], + args = [], + i; + for (i = 2; i < arguments.length; i++) { + args.push(arguments[i]); + } + for (i = 0; i < count; i++) { + todel.push(this[index + i]); + } + for (; i < this.length - index; i++) { + tail.push(this[index + i]); + } + var arglen = args.length; + for (i = 0; i < arglen + tail.length; i++) { + this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen]; + } + i = this.items.length = this.length -= count - arglen; + while (this[i]) { + delete this[i++]; + } + return new Set(todel); + }; + /*\ + * Set.exclude + [ method ] + ** + * Removes given element from the set + ** + - element (object) element to remove + = (boolean) `true` if object was found and removed from the set + \*/ + setproto.exclude = function (el) { + for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) { + this.splice(i, 1); + return true; + } + return false; + }; + setproto.insertAfter = function (el) { + var i = this.items.length; + while (i--) { + this.items[i].insertAfter(el); + } + return this; + }; + setproto.getBBox = function () { + var x = [], + y = [], + x2 = [], + y2 = []; + for (var i = this.items.length; i--;) if (!this.items[i].removed) { + var box = this.items[i].getBBox(); + x.push(box.x); + y.push(box.y); + x2.push(box.x + box.width); + y2.push(box.y + box.height); + } + x = mmin.apply(0, x); + y = mmin.apply(0, y); + x2 = mmax.apply(0, x2); + y2 = mmax.apply(0, y2); + return { + x: x, + y: y, + x2: x2, + y2: y2, + width: x2 - x, + height: y2 - y, + cx: x + (x2 - x) / 2, + cy: y + (y2 - y) / 2 + }; + }; + setproto.clone = function (s) { + s = new Set; + for (var i = 0, ii = this.items.length; i < ii; i++) { + s.push(this.items[i].clone()); + } + return s; + }; + setproto.toString = function () { + return "Snap\u2018s set"; + }; + setproto.type = "set"; + // export + Snap.set = function () { + var set = new Set; + if (arguments.length) { + set.push.apply(set, Array.prototype.slice.call(arguments, 0)); + } + return set; + }; +}); +// 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) { + var names = {}, + reUnit = /[a-z]+$/i, + Str = String; + names.stroke = names.fill = "colour"; + function getEmpty(item) { + var l = item[0]; + switch (l.toLowerCase()) { + case "t": return [l, 0, 0]; + case "m": return [l, 1, 0, 0, 1, 0, 0]; + case "r": if (item.length == 4) { + return [l, 0, item[2], item[3]]; + } else { + return [l, 0]; + } + case "s": if (item.length == 5) { + return [l, 1, 1, item[3], item[4]]; + } else if (item.length == 3) { + return [l, 1, 1]; + } else { + return [l, 1]; + } + } + } + function equaliseTransform(t1, t2, getBBox) { + t2 = Str(t2).replace(/\.{3}|\u2026/g, t1); + t1 = Snap.parseTransformString(t1) || []; + t2 = Snap.parseTransformString(t2) || []; + var maxlength = Math.max(t1.length, t2.length), + from = [], + to = [], + i = 0, j, jj, + tt1, tt2; + for (; i < maxlength; i++) { + tt1 = t1[i] || getEmpty(t2[i]); + tt2 = t2[i] || getEmpty(tt1); + if ((tt1[0] != tt2[0]) || + (tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) || + (tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4])) + ) { + t1 = Snap._.transform2matrix(t1, getBBox()); + t2 = Snap._.transform2matrix(t2, getBBox()); + from = [["m", t1.a, t1.b, t1.c, t1.d, t1.e, t1.f]]; + to = [["m", t2.a, t2.b, t2.c, t2.d, t2.e, t2.f]]; + break; + } + from[i] = []; + to[i] = []; + for (j = 0, jj = Math.max(tt1.length, tt2.length); j < jj; j++) { + j in tt1 && (from[i][j] = tt1[j]); + j in tt2 && (to[i][j] = tt2[j]); + } + } + return { + from: path2array(from), + to: path2array(to), + f: getPath(from) + }; + } + function getNumber(val) { + return val; + } + function getUnit(unit) { + return function (val) { + return +val.toFixed(3) + unit; + }; + } + function getColour(clr) { + return Snap.rgb(clr[0], clr[1], clr[2]); + } + function getPath(path) { + var k = 0, i, ii, j, jj, out, a, b = []; + for (i = 0, ii = path.length; i < ii; i++) { + out = "["; + a = ['"' + path[i][0] + '"']; + for (j = 1, jj = path[i].length; j < jj; j++) { + a[j] = "val[" + (k++) + "]"; + } + out += a + "]"; + b[i] = out; + } + return Function("val", "return Snap.path.toString.call([" + b + "])"); + } + function path2array(path) { + var out = []; + for (var i = 0, ii = path.length; i < ii; i++) { + for (var j = 1, jj = path[i].length; j < jj; j++) { + out.push(path[i][j]); + } + } + return out; + } + Element.prototype.equal = function (name, b) { + var A, B, a = Str(this.attr(name) || ""), + el = this; + if (a == +a && b == +b) { + return { + from: +a, + to: +b, + f: getNumber + }; + } + if (names[name] == "colour") { + A = Snap.color(a); + B = Snap.color(b); + return { + from: [A.r, A.g, A.b, A.opacity], + to: [B.r, B.g, B.b, B.opacity], + f: getColour + }; + } + if (name == "transform" || name == "gradientTransform" || name == "patternTransform") { + if (b instanceof Snap.Matrix) { + b = b.toTransformString(); + } + if (!Snap._.rgTransform.test(b)) { + b = Snap._.svgTransform2string(b); + } + return equaliseTransform(a, b, function () { + return el.getBBox(1); + }); + } + if (name == "d" || name == "path") { + A = Snap.path.toCubic(a, b); + return { + from: path2array(A[0]), + to: path2array(A[1]), + f: getPath(A[0]) + }; + } + if (name == "points") { + A = Str(a).split(","); + B = Str(b).split(","); + return { + from: A, + to: B, + f: function (val) { return val; } + }; + } + var aUnit = a.match(reUnit), + bUnit = Str(b).match(reUnit); + if (aUnit && aUnit == bUnit) { + return { + from: parseFloat(a), + to: parseFloat(b), + f: getUnit(aUnit) + }; + } else { + return { + from: this.asPX(name), + to: this.asPX(name, b), + f: getNumber + }; + } + }; +}); +// 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) { + var elproto = Element.prototype, + has = "hasOwnProperty", + supportsTouch = "createTouch" in glob.doc, + events = [ + "click", "dblclick", "mousedown", "mousemove", "mouseout", + "mouseover", "mouseup", "touchstart", "touchmove", "touchend", + "touchcancel" + ], + touchMap = { + mousedown: "touchstart", + mousemove: "touchmove", + mouseup: "touchend" + }, + getScroll = function (xy) { + var name = xy == "y" ? "scrollTop" : "scrollLeft"; + return glob.doc.documentElement[name] || glob.doc.body[name]; + }, + preventDefault = function () { + this.returnValue = false; + }, + preventTouch = function () { + return this.originalEvent.preventDefault(); + }, + stopPropagation = function () { + this.cancelBubble = true; + }, + stopTouch = function () { + return this.originalEvent.stopPropagation(); + }, + addEvent = (function () { + if (glob.doc.addEventListener) { + return function (obj, type, fn, element) { + var realName = supportsTouch && touchMap[type] ? touchMap[type] : type, + f = function (e) { + var scrollY = getScroll("y"), + scrollX = getScroll("x"); + if (supportsTouch && touchMap[has](type)) { + for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) { + if (e.targetTouches[i].target == obj || obj.contains(e.targetTouches[i].target)) { + var olde = e; + e = e.targetTouches[i]; + e.originalEvent = olde; + e.preventDefault = preventTouch; + e.stopPropagation = stopTouch; + break; + } + } + } + var x = e.clientX + scrollX, + y = e.clientY + scrollY; + return fn.call(element, e, x, y); + }; + + if (type !== realName) { + obj.addEventListener(type, f, false); + } + + obj.addEventListener(realName, f, false); + + return function () { + if (type !== realName) { + obj.removeEventListener(type, f, false); + } + + obj.removeEventListener(realName, f, false); + return true; + }; + }; + } else if (glob.doc.attachEvent) { + return function (obj, type, fn, element) { + var f = function (e) { + e = e || glob.win.event; + var scrollY = getScroll("y"), + scrollX = getScroll("x"), + x = e.clientX + scrollX, + y = e.clientY + scrollY; + e.preventDefault = e.preventDefault || preventDefault; + e.stopPropagation = e.stopPropagation || stopPropagation; + return fn.call(element, e, x, y); + }; + obj.attachEvent("on" + type, f); + var detacher = function () { + obj.detachEvent("on" + type, f); + return true; + }; + return detacher; + }; + } + })(), + drag = [], + dragMove = function (e) { + var x = e.clientX, + y = e.clientY, + scrollY = getScroll("y"), + scrollX = getScroll("x"), + dragi, + j = drag.length; + while (j--) { + dragi = drag[j]; + if (supportsTouch) { + var i = e.touches && e.touches.length, + touch; + while (i--) { + touch = e.touches[i]; + if (touch.identifier == dragi.el._drag.id || dragi.el.node.contains(touch.target)) { + x = touch.clientX; + y = touch.clientY; + (e.originalEvent ? e.originalEvent : e).preventDefault(); + break; + } + } + } else { + e.preventDefault(); + } + var node = dragi.el.node, + o, + glob = Snap._.glob, + next = node.nextSibling, + parent = node.parentNode, + display = node.style.display; + // glob.win.opera && parent.removeChild(node); + // node.style.display = "none"; + // o = dragi.el.paper.getElementByPoint(x, y); + // node.style.display = display; + // glob.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node)); + // o && eve("snap.drag.over." + dragi.el.id, dragi.el, o); + x += scrollX; + y += scrollY; + eve("snap.drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e); + } + }, + dragUp = function (e) { + Snap.unmousemove(dragMove).unmouseup(dragUp); + var i = drag.length, + dragi; + while (i--) { + dragi = drag[i]; + dragi.el._drag = {}; + eve("snap.drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e); + } + drag = []; + }; + /*\ + * Element.click + [ method ] + ** + * Adds a click event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unclick + [ method ] + ** + * Removes a click event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.dblclick + [ method ] + ** + * Adds a double click event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.undblclick + [ method ] + ** + * Removes a double click event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mousedown + [ method ] + ** + * Adds a mousedown event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmousedown + [ method ] + ** + * Removes a mousedown event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mousemove + [ method ] + ** + * Adds a mousemove event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmousemove + [ method ] + ** + * Removes a mousemove event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mouseout + [ method ] + ** + * Adds a mouseout event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmouseout + [ method ] + ** + * Removes a mouseout event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mouseover + [ method ] + ** + * Adds a mouseover event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmouseover + [ method ] + ** + * Removes a mouseover event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.mouseup + [ method ] + ** + * Adds a mouseup event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.unmouseup + [ method ] + ** + * Removes a mouseup event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.touchstart + [ method ] + ** + * Adds a touchstart event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.untouchstart + [ method ] + ** + * Removes a touchstart event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.touchmove + [ method ] + ** + * Adds a touchmove event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.untouchmove + [ method ] + ** + * Removes a touchmove event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.touchend + [ method ] + ** + * Adds a touchend event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.untouchend + [ method ] + ** + * Removes a touchend event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + + /*\ + * Element.touchcancel + [ method ] + ** + * Adds a touchcancel event handler to the element + - handler (function) handler for the event + = (object) @Element + \*/ + /*\ + * Element.untouchcancel + [ method ] + ** + * Removes a touchcancel event handler from the element + - handler (function) handler for the event + = (object) @Element + \*/ + for (var i = events.length; i--;) { + (function (eventName) { + Snap[eventName] = elproto[eventName] = function (fn, scope) { + if (Snap.is(fn, "function")) { + this.events = this.events || []; + this.events.push({ + name: eventName, + f: fn, + unbind: addEvent(this.shape || this.node || glob.doc, eventName, fn, scope || this) + }); + } + return this; + }; + Snap["un" + eventName] = + elproto["un" + eventName] = function (fn) { + var events = this.events || [], + l = events.length; + while (l--) if (events[l].name == eventName && + (events[l].f == fn || !fn)) { + events[l].unbind(); + events.splice(l, 1); + !events.length && delete this.events; + return this; + } + return this; + }; + })(events[i]); + } + /*\ + * Element.hover + [ method ] + ** + * Adds hover event handlers to the element + - f_in (function) handler for hover in + - f_out (function) handler for hover out + - icontext (object) #optional context for hover in handler + - ocontext (object) #optional context for hover out handler + = (object) @Element + \*/ + elproto.hover = function (f_in, f_out, scope_in, scope_out) { + return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in); + }; + /*\ + * Element.unhover + [ method ] + ** + * Removes hover event handlers from the element + - f_in (function) handler for hover in + - f_out (function) handler for hover out + = (object) @Element + \*/ + elproto.unhover = function (f_in, f_out) { + return this.unmouseover(f_in).unmouseout(f_out); + }; + var draggable = []; + // SIERRA unclear what _context_ refers to for starting, ending, moving the drag gesture. + // SIERRA Element.drag(): _x position of the mouse_: Where are the x/y values offset from? + // SIERRA Element.drag(): much of this member's doc appears to be duplicated for some reason. + // SIERRA Unclear about this sentence: _Additionally following drag events will be triggered: drag.start. on start, drag.end. on end and drag.move. on every move._ Is there a global _drag_ object to which you can assign handlers keyed by an element's ID? + /*\ + * Element.drag + [ method ] + ** + * Adds event handlers for an element's drag gesture + ** + - onmove (function) handler for moving + - onstart (function) handler for drag start + - onend (function) handler for drag end + - mcontext (object) #optional context for moving handler + - scontext (object) #optional context for drag start handler + - econtext (object) #optional context for drag end handler + * Additionaly following `drag` events are triggered: `drag.start.` on start, + * `drag.end.` on end and `drag.move.` on every move. When element is dragged over another element + * `drag.over.` fires as well. + * + * Start event and start handler are called in specified context or in context of the element with following parameters: + o x (number) x position of the mouse + o y (number) y position of the mouse + o event (object) DOM event object + * Move event and move handler are called in specified context or in context of the element with following parameters: + o dx (number) shift by x from the start point + o dy (number) shift by y from the start point + o x (number) x position of the mouse + o y (number) y position of the mouse + o event (object) DOM event object + * End event and end handler are called in specified context or in context of the element with following parameters: + o event (object) DOM event object + = (object) @Element + \*/ + elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) { + if (!arguments.length) { + var origTransform; + return this.drag(function (dx, dy) { + this.attr({ + transform: origTransform + (origTransform ? "T" : "t") + [dx, dy] + }); + }, function () { + origTransform = this.transform().local; + }); + } + function start(e, x, y) { + (e.originalEvent || e).preventDefault(); + this._drag.x = x; + this._drag.y = y; + this._drag.id = e.identifier; + !drag.length && Snap.mousemove(dragMove).mouseup(dragUp); + drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope}); + onstart && eve.on("snap.drag.start." + this.id, onstart); + onmove && eve.on("snap.drag.move." + this.id, onmove); + onend && eve.on("snap.drag.end." + this.id, onend); + eve("snap.drag.start." + this.id, start_scope || move_scope || this, x, y, e); + } + this._drag = {}; + draggable.push({el: this, start: start}); + this.mousedown(start); + return this; + }; + /* + * Element.onDragOver + [ method ] + ** + * Shortcut to assign event handler for `drag.over.` event, where `id` is the element's `id` (see @Element.id) + - f (function) handler for event, first argument would be the element you are dragging over + \*/ + // elproto.onDragOver = function (f) { + // f ? eve.on("snap.drag.over." + this.id, f) : eve.unbind("snap.drag.over." + this.id); + // }; + /*\ + * Element.undrag + [ method ] + ** + * Removes all drag event handlers from the given element + \*/ + elproto.undrag = function () { + var i = draggable.length; + while (i--) if (draggable[i].el == this) { + this.unmousedown(draggable[i].start); + draggable.splice(i, 1); + eve.unbind("snap.drag.*." + this.id); + } + !draggable.length && Snap.unmousemove(dragMove).unmouseup(dragUp); + return this; + }; +}); +// 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) { + var elproto = Element.prototype, + pproto = Paper.prototype, + rgurl = /^\s*url\((.+)\)/, + Str = String, + $ = Snap._.$; + Snap.filter = {}; +// SIERRA Paper.filter(): I don't understand the note. Does that mean an HTML should dedicate a separate SVG region for a filter definition? What's the advantage over a DEFS? + /*\ + * Paper.filter + [ method ] + ** + * Creates a `` element + ** + - filstr (string) SVG fragment of filter provided as a string + = (object) @Element + * Note: It is recommended to use filters embedded into the page inside an empty SVG element. + > Usage + | var f = paper.filter(''), + | c = paper.circle(10, 10, 10).attr({ + | filter: f + | }); + \*/ + pproto.filter = function (filstr) { + var paper = this; + if (paper.type != "svg") { + paper = paper.paper; + } + var f = Snap.parse(Str(filstr)), + id = Snap._.id(), + width = paper.node.offsetWidth, + height = paper.node.offsetHeight, + filter = $("filter"); + $(filter, { + id: id, + filterUnits: "userSpaceOnUse" + }); + filter.appendChild(f.node); + paper.defs.appendChild(filter); + return new Element(filter); + }; + + eve.on("snap.util.getattr.filter", function () { + eve.stop(); + var p = $(this.node, "filter"); + if (p) { + var match = Str(p).match(rgurl); + return match && Snap.select(match[1]); + } + }); + eve.on("snap.util.attr.filter", function (value) { + if (value instanceof Element && value.type == "filter") { + eve.stop(); + var id = value.node.id; + if (!id) { + $(value.node, {id: value.id}); + id = value.id; + } + $(this.node, { + filter: Snap.url(id) + }); + } + if (!value || value == "none") { + eve.stop(); + this.node.removeAttribute("filter"); + } + }); + /*\ + * Snap.filter.blur + [ method ] + ** + * Returns an SVG markup string for the blur filter + ** + - x (number) amount of horizontal blur, in pixels + - y (number) #optional amount of vertical blur, in pixels + = (string) filter representation + > Usage + | var f = paper.filter(Snap.filter.blur(5, 10)), + | c = paper.circle(10, 10, 10).attr({ + | filter: f + | }); + \*/ + Snap.filter.blur = function (x, y) { + if (x == null) { + x = 2; + } + var def = y == null ? x : [x, y]; + return Snap.format('\', { + def: def + }); + }; + Snap.filter.blur.toString = function () { + return this(); + }; + /*\ + * Snap.filter.shadow + [ method ] + ** + * Returns an SVG markup string for the shadow filter + ** + - dx (number) horizontal shift of the shadow, in pixels + - dy (number) vertical shift of the shadow, in pixels + - blur (number) #optional amount of blur + - color (string) #optional color of the shadow + = (string) filter representation + > Usage + | var f = paper.filter(Snap.filter.shadow(0, 2, 3)), + | c = paper.circle(10, 10, 10).attr({ + | filter: f + | }); + \*/ + Snap.filter.shadow = function (dx, dy, blur, color) { + color = color || "#000"; + if (blur == null) { + blur = 4; + } + if (typeof blur == "string") { + color = blur; + blur = 4; + } + if (dx == null) { + dx = 0; + dy = 2; + } + if (dy == null) { + dy = dx; + } + color = Snap.color(color); + return Snap.format('', { + color: color, + dx: dx, + dy: dy, + blur: blur + }); + }; + Snap.filter.shadow.toString = function () { + return this(); + }; + /*\ + * Snap.filter.grayscale + [ method ] + ** + * Returns an SVG markup string for the grayscale filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.grayscale = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + a: 0.2126 + 0.7874 * (1 - amount), + b: 0.7152 - 0.7152 * (1 - amount), + c: 0.0722 - 0.0722 * (1 - amount), + d: 0.2126 - 0.2126 * (1 - amount), + e: 0.7152 + 0.2848 * (1 - amount), + f: 0.0722 - 0.0722 * (1 - amount), + g: 0.2126 - 0.2126 * (1 - amount), + h: 0.0722 + 0.9278 * (1 - amount) + }); + }; + Snap.filter.grayscale.toString = function () { + return this(); + }; + /*\ + * Snap.filter.sepia + [ method ] + ** + * Returns an SVG markup string for the sepia filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.sepia = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + a: 0.393 + 0.607 * (1 - amount), + b: 0.769 - 0.769 * (1 - amount), + c: 0.189 - 0.189 * (1 - amount), + d: 0.349 - 0.349 * (1 - amount), + e: 0.686 + 0.314 * (1 - amount), + f: 0.168 - 0.168 * (1 - amount), + g: 0.272 - 0.272 * (1 - amount), + h: 0.534 - 0.534 * (1 - amount), + i: 0.131 + 0.869 * (1 - amount) + }); + }; + Snap.filter.sepia.toString = function () { + return this(); + }; + /*\ + * Snap.filter.saturate + [ method ] + ** + * Returns an SVG markup string for the saturate filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.saturate = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + amount: 1 - amount + }); + }; + Snap.filter.saturate.toString = function () { + return this(); + }; + /*\ + * Snap.filter.hueRotate + [ method ] + ** + * Returns an SVG markup string for the hue-rotate filter + ** + - angle (number) angle of rotation + = (string) filter representation + \*/ + Snap.filter.hueRotate = function (angle) { + angle = angle || 0; + return Snap.format('', { + angle: angle + }); + }; + Snap.filter.hueRotate.toString = function () { + return this(); + }; + /*\ + * Snap.filter.invert + [ method ] + ** + * Returns an SVG markup string for the invert filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.invert = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + amount: amount, + amount2: 1 - amount + }); + }; + Snap.filter.invert.toString = function () { + return this(); + }; + /*\ + * Snap.filter.brightness + [ method ] + ** + * Returns an SVG markup string for the brightness filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.brightness = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + amount: amount + }); + }; + Snap.filter.brightness.toString = function () { + return this(); + }; + /*\ + * Snap.filter.contrast + [ method ] + ** + * Returns an SVG markup string for the contrast filter + ** + - amount (number) amount of filter (`0..1`) + = (string) filter representation + \*/ + Snap.filter.contrast = function (amount) { + if (amount == null) { + amount = 1; + } + return Snap.format('', { + amount: amount, + amount2: .5 - amount / 2 + }); + }; + Snap.filter.contrast.toString = function () { + return this(); + }; +}); +return Snap; +})); \ No newline at end of file diff --git a/demos/snap-ad/src/sass/screen.scss b/demos/snap-ad/src/sass/screen.scss new file mode 100644 index 0000000..e0a5ee4 --- /dev/null +++ b/demos/snap-ad/src/sass/screen.scss @@ -0,0 +1,82 @@ +@import 'compass/css3'; + +.base-font{ + font-family: 'Open Sans', serif; +} + +.snap-font{ + font-family: 'Source Sans Pro', serif; +} + +body{ + margin: 0; + cursor: pointer; +} + +text{ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +svg{ + @include transform-origin(top, left); + @include transform(scale(1)); +} + +#learn-btn{ + cursor: pointer; + + path, text{ + @include transform(translateY(0)); + } + + &:hover{ + path{ + &:first-child{ + fill: #076656; + + } + } + + path{ + &:nth-child(2){ + fill: #7cd1c2; + } + } + + text{ + fill: #0a9a87; + + } + }; + + &:active{ + path{ + &:nth-child(2){ + @include transform(translateY(2px)); + } + } + + text{ + @include transform(translateY(2px)); + } + } +} + +#replay-btn{ + &:hover{ + opacity: 0.5; + }; +} + +/* +@media (max-width: 400px) { + svg{ + @include transform(scale(0.375)); + } +} +*/ \ No newline at end of file