├── CHANGELOG.md ├── CREDITS.md ├── LICENSE.md ├── README.md ├── excanvas ├── README ├── excanvas.compiled.js └── excanvas.js ├── mootools ├── mootools-core-1.3.2.js └── mootools-more-1.3.2.1.js ├── package.json ├── rhill-voronoi-core.js ├── rhill-voronoi-core.min.js ├── rhill-voronoi-demo1.html ├── rhill-voronoi-demo2.html ├── rhill-voronoi-demo3.php ├── rhill-voronoi-demo4.html ├── rhill-voronoi-demo5.html └── rhill-voronoi.html /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG.md 2 | 3 | ## 0.99 (22 Apr 2013): 4 | 5 | Now returning all the unique vertices linking all the edges. This addresses 6 | issue #4: https://github.com/gorhill/Javascript-Voronoi/issues/4 7 | 8 | ## 0.98 (25 Jan 2013): 9 | 10 | Added Cell.getBbox() and Cell.pointIntersection() for convenience when using 11 | an external treemap. 12 | 13 | ## 0.97 (21 Jan 2013): 14 | 15 | Merged contribution by Jesse Morgan (https://github.com/morgajel): 16 | Cell.getNeighbourIds() 17 | https://github.com/gorhill/Javascript-Voronoi/commit/4c50f691a301cd6a286359fefba1fab30c8e3b89 18 | 19 | ## 0.96 (26 May 2011): 20 | 21 | Returned diagram.cells is now an array, whereas the index of a cell 22 | matches the index of its associated site in the array of sites passed 23 | to Voronoi.compute(). This allowed some gain in performance. The 24 | 'voronoiId' member is still used internally by the Voronoi object. 25 | The Voronoi.Cells object is no longer necessary and has been removed. 26 | 27 | ## 0.95 (19 May 2011): 28 | 29 | No longer using Javascript array to keep track of the beach sections of 30 | the beachline, now using Red-Black tree. 31 | 32 | The move to a binary tree was unavoidable, as I ran into finite precision 33 | arithmetic problems when I started to use sites with fractional values. 34 | 35 | The problem arose when the code had to find the arc associated with a 36 | triggered Fortune circle event: the collapsing arc was not always properly 37 | found due to finite precision arithmetic-related errors. Using a tree structure 38 | eliminate the need to look-up a beachsection in the array structure 39 | (findDeletionPoint()), and allowed to bring back epsilon down to 1e-9. 40 | 41 | ## 0.91(21 September 2010): 42 | 43 | Lower epsilon from 1e-5 to 1e-4, to fix problem reported at 44 | http://www.raymondhill.net/blog/?p=9#comment-1414 45 | 46 | ## 0.90 (21 September 2010): 47 | 48 | First version. 49 | 50 | -------------------------------------------------------------------------------- /CREDITS.md: -------------------------------------------------------------------------------- 1 | # CREDITS.md 2 | 3 | ## Portions of this software use, depend, or was inspired by the work of: 4 | 5 | ## "Fortune's algorithm" by Steven J. Fortune 6 | 7 | For his clever algorithm to compute Voronoi diagrams. 8 | 9 | http://ect.bell-labs.com/who/sjf/ 10 | 11 | ## "The Liang-Barsky line clipping algorithm in a nutshell!" by Daniel White 12 | 13 | To efficiently clip a line within a rectangle. 14 | 15 | http://www.skytopia.com/project/articles/compsci/clipping.html 16 | 17 | ## "rbtree" by Franck Bui-Huu 18 | 19 | For his RB-tree C implmentation. 20 | 21 | I ported to Javascript the C code of a Red-Black tree implementation by 22 | Franck Bui-Huu, and further altered the code for Javascript efficiency 23 | and to very specifically fit the purpose of holding the beachline (the key 24 | is a variable range rather than an unmutable data point), and unused 25 | code paths have been removed. 26 | 27 | Each node in the tree is actually a beach section on the beachline. Using a 28 | tree structure for the beachline remove the need to lookup the beach section 29 | in the array at removal time, as now a circle event can safely hold a 30 | reference to its associated beach section (thus findDeletionPoint() is no 31 | longer needed). 32 | 33 | This finally take care of nagging finite arithmetic precision issues arising 34 | at lookup time, such that epsilon could be brought down to 1e-9 (from 1e-4). 35 | rhill 2011-05-27: added a 'previous' and 'next' members which keeps track 36 | of previous and next nodes, and remove the need for Beachsection.getPrevious() 37 | and Beachsection.getNext(). 38 | 39 | https://github.com/fbuihuu/libtree/blob/master/rb.c 40 | 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010-2013 Raymond Hill 2 | https://github.com/gorhill/Javascript-Voronoi 3 | 4 | Licensed under The MIT License 5 | http://en.wikipedia.org/wiki/MIT_License 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Javascript-Voronoi 2 | 3 | A Javascript implementation of Steven J. Fortune's algorithm to 4 | efficiently compute Voronoi diagrams. The Voronoi object's purpose is 5 | to solely compute a Voronoi diagram, it is completely standalone, with 6 | no dependency on external code: it contains no rendering code: that is 7 | left to the user of the library. 8 | 9 | ## Core files 10 | 11 | * rhill-voronoi-core.js 12 | 13 | Where the Voronoi object is implemented. This is a standalone library, there 14 | is no dependency. 15 | 16 | * rhill-voronoi-core.min.js 17 | 18 | The minimized version (using YUI compressor) 19 | 20 | ## Demo files 21 | 22 | * rhill-voronoi-demo1.html 23 | * rhill-voronoi-demo2.html 24 | * rhill-voronoi-demo3.php 25 | * rhill-voronoi-demo4.html 26 | * rhill-voronoi-demo5.html 27 | 28 | Demo pages to demonstrate usage of the Voronoi object. 29 | 30 | * excanvas/* 31 | 32 | Used by demo pages. 33 | 34 | ExplorerCanvas, giving pre-HTML5 Internet Explorer the ability to make sense 35 | of HTML5's canvas element. Pulled from http://code.google.com/p/explorercanvas/ 36 | 37 | * mootools/* 38 | 39 | Used by rhill-voronoi-demo3.php 40 | 41 | * Above pages available at http://www.raymondhill.net/voronoi/ 42 | 43 | 44 | ## Main object: Voronoi 45 | 46 | A Javascript object which allows to compute a Voronoi diagram. 47 | The Voronoi object doesn't render the resulting Voronoi diagram, 48 | the user is responsible for rendering the diagram. 49 | 50 | ## Usage 51 | 52 | Roughly: 53 | 54 | ``` javascript 55 | var voronoi = new Voronoi(); 56 | var bbox = {xl: 0, xr: 800, yt: 0, yb: 600}; // xl is x-left, xr is x-right, yt is y-top, and yb is y-bottom 57 | var sites = [ {x: 200, y: 200}, {x: 50, y: 250}, {x: 400, y: 100} /* , ... */ ]; 58 | 59 | // a 'vertex' is an object exhibiting 'x' and 'y' properties. The 60 | // Voronoi object will add a unique 'voronoiId' property to all 61 | // sites. The 'voronoiId' can be used as a key to lookup the associated cell 62 | // in diagram.cells. 63 | 64 | var diagram = voronoi.compute(sites, bbox); 65 | ``` 66 | 67 | The returned 'diagram' variable is a Javascript object with the 68 | following properties: 69 | 70 | ``` 71 | diagram.vertices 72 | ``` 73 | 74 | An array of unordered, unique ```Voronoi.Vertex``` objects making up the 75 | Voronoi diagram. Each ```Voronoi.Vertex``` object in the list is shared by 76 | many ```Voronoi.Edge``` objects. 77 | 78 | ``` 79 | diagram.edges 80 | ``` 81 | 82 | An array of unordered, unique ```Voronoi.Edge``` objects making up the 83 | Voronoi diagram. ```Voronoi.Edges``` are defined by two vertices, 84 | ```va``` and ```vb```, which vertices are shared by connected edges. This mean 85 | that if you change one vertex belonging to an edge, other connected edges 86 | will also be changed. 87 | 88 | ``` 89 | diagram.cells 90 | ``` 91 | 92 | An array of ```Voronoi.Cell``` objects making up the Voronoi diagram. A 93 | ```Voronoi.Cell``` object might have an empty array of ```halfedges```, 94 | meaning no Voronoi cell could be computed for a particular cell. 95 | 96 | ``` 97 | diagram.execTime 98 | ``` 99 | 100 | The time it took to compute the Voronoi diagram, in milliseconds. 101 | 102 | Added on October 12, 2013: In order to help improve performance, 103 | `Voronoi.recycle()` has been added to allow the recycling of a returned Voronoi 104 | diagram. Usage: 105 | 106 | ``` javascript 107 | var diagram; 108 | ... 109 | 110 | // some kind of loop starting here (whether outright or through a timer) 111 | ... 112 | 113 | voronoi.recycle(diagram); 114 | // diagram.vertices, diagram.edges and diagram.cells can no longer be used! 115 | diagram = voronoi.compute(sites, bbox); 116 | 117 | // do stuff with content of `diagram` 118 | ... 119 | ``` 120 | 121 | This new method helps performance significantly when re-computing a Voronoi 122 | diagram, as it saves on memory allocation, and associated garbage collection. 123 | 124 | ## Public objects 125 | 126 | ``` 127 | Voronoi 128 | ``` 129 | 130 | The ```Voronoi``` object which computes a Voronoi diagram. 131 | 132 | ``` 133 | Voronoi.Vertex 134 | ``` 135 | 136 | * ```x```: no explanation required. 137 | 138 | * ```y```: no explanation required. 139 | 140 | ``` 141 | Voronoi.Edge 142 | ``` 143 | 144 | * ```lSite```: the Voronoi site object at the left of this ```Voronoi.Edge``` 145 | object. The site object is just a reference to a site in the array of sites 146 | supplied by the user when ```Voronoi.compute()``` was called. 147 | 148 | * ```rSite```: the Voronoi site object at the right of this ```Voronoi.Edge``` 149 | object (can be null, when this is a border edge). The site object is just a 150 | reference to a site in the array of sites supplied by the user when 151 | ```Voronoi.compute()``` was called. 152 | 153 | * ```va```: a ```Voronoi.Vertex``` object with an ```x``` and a ```y``` 154 | property defining the start point (relative to the Voronoi site on 155 | the left) of this ```Voronoi.Edge``` object. 156 | 157 | * ```vb```: a ```Voronoi.Vertex``` object with an ```x``` and a ```y``` 158 | property defining the end point (relative to Voronoi site on the left) 159 | of this ```Voronoi.Edge``` object. 160 | 161 | ``` 162 | Voronoi.Cell 163 | ``` 164 | 165 | * ```site```: the Voronoi site object associated with the Voronoi cell. 166 | 167 | * ```halfedges```: an array of ```Voronoi.Halfedge``` objects, ordered 168 | counterclockwise, defining the polygon for this Voronoi cell. 169 | 170 | ``` 171 | Voronoi.Halfedge 172 | ``` 173 | 174 | * ```site```: the Voronoi site object owning this ```Voronoi.Halfedge``` 175 | object. 176 | 177 | * ```edge```: a reference to the unique ```Voronoi.Edge``` object underlying 178 | this ```Voronoi.Halfedge``` object. 179 | 180 | * ```getStartpoint()```: a method returning a ```Voronoi.Vertex``` of the start 181 | point of this halfedge. Keep in mind halfedges are always counterclockwise. 182 | 183 | * ```getEndpoint()```: a method returning a ```Voronoi.Vertex``` object with 184 | an ```x``` and a ```y``` property for the end point of this halfedge. Keep in 185 | mind halfedges are always counterclockwise. 186 | 187 | ## License 188 | 189 | Copyright (c) 2010-2013 Raymond Hill 190 | https://github.com/gorhill/Javascript-Voronoi 191 | 192 | Licensed under The MIT License 193 | http://en.wikipedia.org/wiki/MIT_License 194 | 195 | Permission is hereby granted, free of charge, to any person obtaining a copy 196 | of this software and associated documentation files (the "Software"), to deal 197 | in the Software without restriction, including without limitation the rights 198 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 199 | copies of the Software, and to permit persons to whom the Software is 200 | furnished to do so, subject to the following conditions: 201 | 202 | The above copyright notice and this permission notice shall be included in 203 | all copies or substantial portions of the Software. 204 | 205 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 206 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 207 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 208 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 209 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 210 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 211 | THE SOFTWARE. 212 | -------------------------------------------------------------------------------- /excanvas/README: -------------------------------------------------------------------------------- 1 | ExplorerCanvas 2 | Copyright 2006 Google Inc. 3 | 4 | ------------------------------------------------------------------------------- 5 | DESCRIPTION 6 | 7 | Firefox, Safari and Opera 9 support the canvas tag to allow 2D command-based 8 | drawing operations. ExplorerCanvas brings the same functionality to Internet 9 | Explorer; web developers only need to include a single script tag in their 10 | existing canvas webpages to enable this support. 11 | 12 | 13 | ------------------------------------------------------------------------------- 14 | INSTALLATION 15 | 16 | Include the ExplorerCanvas tag in the same directory as your HTML files, and 17 | add the following code to your page, preferably in the tag. 18 | 19 | 20 | 21 | If you run into trouble, please look at the included example code to see how 22 | to best implement this -------------------------------------------------------------------------------- /excanvas/excanvas.compiled.js: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | document.createElement("canvas").getContext||(function(){var s=Math,j=s.round,F=s.sin,G=s.cos,V=s.abs,W=s.sqrt,k=10,v=k/2;function X(){return this.context_||(this.context_=new H(this))}var L=Array.prototype.slice;function Y(b,a){var c=L.call(arguments,2);return function(){return b.apply(a,c.concat(L.call(arguments)))}}var M={init:function(b){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var a=b||document;a.createElement("canvas");a.attachEvent("onreadystatechange",Y(this.init_,this,a))}},init_:function(b){b.namespaces.g_vml_|| 15 | b.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML");b.namespaces.g_o_||b.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML");if(!b.styleSheets.ex_canvas_){var a=b.createStyleSheet();a.owningElement.id="ex_canvas_";a.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var c=b.getElementsByTagName("canvas"),d=0;for(;d','","");this.element_.insertAdjacentHTML("BeforeEnd",t.join(""))};i.stroke=function(b){var a=[],c=P(b?this.fillStyle:this.strokeStyle),d=c.color,f=c.alpha*this.globalAlpha;a.push("g.x)g.x=e.x;if(h.y==null||e.yg.y)g.y=e.y}}a.push(' ">');if(b)if(typeof this.fillStyle=="object"){var m=this.fillStyle,r=0,n={x:0,y:0},o=0,q=1;if(m.type_=="gradient"){var t=m.x1_/this.arcScaleX_,E=m.y1_/this.arcScaleY_,p=this.getCoords_(m.x0_/this.arcScaleX_,m.y0_/this.arcScaleY_), 30 | z=this.getCoords_(t,E);r=Math.atan2(z.x-p.x,z.y-p.y)*180/Math.PI;if(r<0)r+=360;if(r<1.0E-6)r=0}else{var p=this.getCoords_(m.x0_,m.y0_),w=g.x-h.x,x=g.y-h.y;n={x:(p.x-h.x)/w,y:(p.y-h.y)/x};w/=this.arcScaleX_*k;x/=this.arcScaleY_*k;var R=s.max(w,x);o=2*m.r0_/R;q=2*m.r1_/R-o}var u=m.colors_;u.sort(function(ba,ca){return ba.offset-ca.offset});var J=u.length,da=u[0].color,ea=u[J-1].color,fa=u[0].alpha*this.globalAlpha,ga=u[J-1].alpha*this.globalAlpha,S=[],l=0;for(;l')}else a.push('');else{var K=this.lineScale_*this.lineWidth;if(K<1)f*=K;a.push("')}a.push("");this.element_.insertAdjacentHTML("beforeEnd",a.join(""))};i.fill=function(){this.stroke(true)};i.closePath=function(){this.currentPath_.push({type:"close"})};i.getCoords_=function(b,a){var c=this.m_;return{x:k*(b*c[0][0]+a*c[1][0]+c[2][0])-v,y:k*(b*c[0][1]+a*c[1][1]+c[2][1])-v}};i.save=function(){var b={};O(this,b);this.aStack_.push(b);this.mStack_.push(this.m_);this.m_=y(I(),this.m_)};i.restore=function(){O(this.aStack_.pop(), 33 | this);this.m_=this.mStack_.pop()};function ha(b){var a=0;for(;a<3;a++){var c=0;for(;c<2;c++)if(!isFinite(b[a][c])||isNaN(b[a][c]))return false}return true}function A(b,a,c){if(!!ha(a)){b.m_=a;if(c)b.lineScale_=W(V(a[0][0]*a[1][1]-a[0][1]*a[1][0]))}}i.translate=function(b,a){A(this,y([[1,0,0],[0,1,0],[b,a,1]],this.m_),false)};i.rotate=function(b){var a=G(b),c=F(b);A(this,y([[a,c,0],[-c,a,0],[0,0,1]],this.m_),false)};i.scale=function(b,a){this.arcScaleX_*=b;this.arcScaleY_*=a;A(this,y([[b,0,0],[0,a, 34 | 0],[0,0,1]],this.m_),true)};i.transform=function(b,a,c,d,f,h){A(this,y([[b,a,0],[c,d,0],[f,h,1]],this.m_),true)};i.setTransform=function(b,a,c,d,f,h){A(this,[[b,a,0],[c,d,0],[f,h,1]],true)};i.clip=function(){};i.arcTo=function(){};i.createPattern=function(){return new U};function D(b){this.type_=b;this.r1_=this.y1_=this.x1_=this.r0_=this.y0_=this.x0_=0;this.colors_=[]}D.prototype.addColorStop=function(b,a){a=P(a);this.colors_.push({offset:b,color:a.color,alpha:a.alpha})};function U(){}G_vmlCanvasManager= 35 | M;CanvasRenderingContext2D=H;CanvasGradient=D;CanvasPattern=U})(); 36 | -------------------------------------------------------------------------------- /excanvas/excanvas.js: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | // Known Issues: 17 | // 18 | // * Patterns are not implemented. 19 | // * Radial gradient are not implemented. The VML version of these look very 20 | // different from the canvas one. 21 | // * Clipping paths are not implemented. 22 | // * Coordsize. The width and height attribute have higher priority than the 23 | // width and height style values which isn't correct. 24 | // * Painting mode isn't implemented. 25 | // * Canvas width/height should is using content-box by default. IE in 26 | // Quirks mode will draw the canvas using border-box. Either change your 27 | // doctype to HTML5 28 | // (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) 29 | // or use Box Sizing Behavior from WebFX 30 | // (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) 31 | // * Non uniform scaling does not correctly scale strokes. 32 | // * Optimize. There is always room for speed improvements. 33 | 34 | // Only add this code if we do not already have a canvas implementation 35 | if (!document.createElement('canvas').getContext) { 36 | 37 | (function() { 38 | 39 | // alias some functions to make (compiled) code shorter 40 | var m = Math; 41 | var mr = m.round; 42 | var ms = m.sin; 43 | var mc = m.cos; 44 | var abs = m.abs; 45 | var sqrt = m.sqrt; 46 | 47 | // this is used for sub pixel precision 48 | var Z = 10; 49 | var Z2 = Z / 2; 50 | 51 | /** 52 | * This funtion is assigned to the elements as element.getContext(). 53 | * @this {HTMLElement} 54 | * @return {CanvasRenderingContext2D_} 55 | */ 56 | function getContext() { 57 | return this.context_ || 58 | (this.context_ = new CanvasRenderingContext2D_(this)); 59 | } 60 | 61 | var slice = Array.prototype.slice; 62 | 63 | /** 64 | * Binds a function to an object. The returned function will always use the 65 | * passed in {@code obj} as {@code this}. 66 | * 67 | * Example: 68 | * 69 | * g = bind(f, obj, a, b) 70 | * g(c, d) // will do f.call(obj, a, b, c, d) 71 | * 72 | * @param {Function} f The function to bind the object to 73 | * @param {Object} obj The object that should act as this when the function 74 | * is called 75 | * @param {*} var_args Rest arguments that will be used as the initial 76 | * arguments when the function is called 77 | * @return {Function} A new function that has bound this 78 | */ 79 | function bind(f, obj, var_args) { 80 | var a = slice.call(arguments, 2); 81 | return function() { 82 | return f.apply(obj, a.concat(slice.call(arguments))); 83 | }; 84 | } 85 | 86 | var G_vmlCanvasManager_ = { 87 | init: function(opt_doc) { 88 | if (/MSIE/.test(navigator.userAgent) && !window.opera) { 89 | var doc = opt_doc || document; 90 | // Create a dummy element so that IE will allow canvas elements to be 91 | // recognized. 92 | doc.createElement('canvas'); 93 | doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); 94 | } 95 | }, 96 | 97 | init_: function(doc) { 98 | // create xmlns 99 | if (!doc.namespaces['g_vml_']) { 100 | doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', 101 | '#default#VML'); 102 | 103 | } 104 | if (!doc.namespaces['g_o_']) { 105 | doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', 106 | '#default#VML'); 107 | } 108 | 109 | // Setup default CSS. Only add one style sheet per document 110 | if (!doc.styleSheets['ex_canvas_']) { 111 | var ss = doc.createStyleSheet(); 112 | ss.owningElement.id = 'ex_canvas_'; 113 | ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + 114 | // default size is 300x150 in Gecko and Opera 115 | 'text-align:left;width:300px;height:150px}' + 116 | 'g_vml_\\:*{behavior:url(#default#VML)}' + 117 | 'g_o_\\:*{behavior:url(#default#VML)}'; 118 | 119 | } 120 | 121 | // find all canvas elements 122 | var els = doc.getElementsByTagName('canvas'); 123 | for (var i = 0; i < els.length; i++) { 124 | this.initElement(els[i]); 125 | } 126 | }, 127 | 128 | /** 129 | * Public initializes a canvas element so that it can be used as canvas 130 | * element from now on. This is called automatically before the page is 131 | * loaded but if you are creating elements using createElement you need to 132 | * make sure this is called on the element. 133 | * @param {HTMLElement} el The canvas element to initialize. 134 | * @return {HTMLElement} the element that was created. 135 | */ 136 | initElement: function(el) { 137 | if (!el.getContext) { 138 | 139 | el.getContext = getContext; 140 | 141 | // Remove fallback content. There is no way to hide text nodes so we 142 | // just remove all childNodes. We could hide all elements and remove 143 | // text nodes but who really cares about the fallback content. 144 | el.innerHTML = ''; 145 | 146 | // do not use inline function because that will leak memory 147 | el.attachEvent('onpropertychange', onPropertyChange); 148 | el.attachEvent('onresize', onResize); 149 | 150 | var attrs = el.attributes; 151 | if (attrs.width && attrs.width.specified) { 152 | // TODO: use runtimeStyle and coordsize 153 | // el.getContext().setWidth_(attrs.width.nodeValue); 154 | el.style.width = attrs.width.nodeValue + 'px'; 155 | } else { 156 | el.width = el.clientWidth; 157 | } 158 | if (attrs.height && attrs.height.specified) { 159 | // TODO: use runtimeStyle and coordsize 160 | // el.getContext().setHeight_(attrs.height.nodeValue); 161 | el.style.height = attrs.height.nodeValue + 'px'; 162 | } else { 163 | el.height = el.clientHeight; 164 | } 165 | //el.getContext().setCoordsize_() 166 | } 167 | return el; 168 | } 169 | }; 170 | 171 | function onPropertyChange(e) { 172 | var el = e.srcElement; 173 | 174 | switch (e.propertyName) { 175 | case 'width': 176 | el.style.width = el.attributes.width.nodeValue + 'px'; 177 | el.getContext().clearRect(); 178 | break; 179 | case 'height': 180 | el.style.height = el.attributes.height.nodeValue + 'px'; 181 | el.getContext().clearRect(); 182 | break; 183 | } 184 | } 185 | 186 | function onResize(e) { 187 | var el = e.srcElement; 188 | if (el.firstChild) { 189 | el.firstChild.style.width = el.clientWidth + 'px'; 190 | el.firstChild.style.height = el.clientHeight + 'px'; 191 | } 192 | } 193 | 194 | G_vmlCanvasManager_.init(); 195 | 196 | // precompute "00" to "FF" 197 | var dec2hex = []; 198 | for (var i = 0; i < 16; i++) { 199 | for (var j = 0; j < 16; j++) { 200 | dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); 201 | } 202 | } 203 | 204 | function createMatrixIdentity() { 205 | return [ 206 | [1, 0, 0], 207 | [0, 1, 0], 208 | [0, 0, 1] 209 | ]; 210 | } 211 | 212 | function matrixMultiply(m1, m2) { 213 | var result = createMatrixIdentity(); 214 | 215 | for (var x = 0; x < 3; x++) { 216 | for (var y = 0; y < 3; y++) { 217 | var sum = 0; 218 | 219 | for (var z = 0; z < 3; z++) { 220 | sum += m1[x][z] * m2[z][y]; 221 | } 222 | 223 | result[x][y] = sum; 224 | } 225 | } 226 | return result; 227 | } 228 | 229 | function copyState(o1, o2) { 230 | o2.fillStyle = o1.fillStyle; 231 | o2.lineCap = o1.lineCap; 232 | o2.lineJoin = o1.lineJoin; 233 | o2.lineWidth = o1.lineWidth; 234 | o2.miterLimit = o1.miterLimit; 235 | o2.shadowBlur = o1.shadowBlur; 236 | o2.shadowColor = o1.shadowColor; 237 | o2.shadowOffsetX = o1.shadowOffsetX; 238 | o2.shadowOffsetY = o1.shadowOffsetY; 239 | o2.strokeStyle = o1.strokeStyle; 240 | o2.globalAlpha = o1.globalAlpha; 241 | o2.arcScaleX_ = o1.arcScaleX_; 242 | o2.arcScaleY_ = o1.arcScaleY_; 243 | o2.lineScale_ = o1.lineScale_; 244 | } 245 | 246 | function processStyle(styleString) { 247 | var str, alpha = 1; 248 | 249 | styleString = String(styleString); 250 | if (styleString.substring(0, 3) == 'rgb') { 251 | var start = styleString.indexOf('(', 3); 252 | var end = styleString.indexOf(')', start + 1); 253 | var guts = styleString.substring(start + 1, end).split(','); 254 | 255 | str = '#'; 256 | for (var i = 0; i < 3; i++) { 257 | str += dec2hex[Number(guts[i])]; 258 | } 259 | 260 | if (guts.length == 4 && styleString.substr(3, 1) == 'a') { 261 | alpha = guts[3]; 262 | } 263 | } else { 264 | str = styleString; 265 | } 266 | 267 | return {color: str, alpha: alpha}; 268 | } 269 | 270 | function processLineCap(lineCap) { 271 | switch (lineCap) { 272 | case 'butt': 273 | return 'flat'; 274 | case 'round': 275 | return 'round'; 276 | case 'square': 277 | default: 278 | return 'square'; 279 | } 280 | } 281 | 282 | /** 283 | * This class implements CanvasRenderingContext2D interface as described by 284 | * the WHATWG. 285 | * @param {HTMLElement} surfaceElement The element that the 2D context should 286 | * be associated with 287 | */ 288 | function CanvasRenderingContext2D_(surfaceElement) { 289 | this.m_ = createMatrixIdentity(); 290 | 291 | this.mStack_ = []; 292 | this.aStack_ = []; 293 | this.currentPath_ = []; 294 | 295 | // Canvas context properties 296 | this.strokeStyle = '#000'; 297 | this.fillStyle = '#000'; 298 | 299 | this.lineWidth = 1; 300 | this.lineJoin = 'miter'; 301 | this.lineCap = 'butt'; 302 | this.miterLimit = Z * 1; 303 | this.globalAlpha = 1; 304 | this.canvas = surfaceElement; 305 | 306 | var el = surfaceElement.ownerDocument.createElement('div'); 307 | el.style.width = surfaceElement.clientWidth + 'px'; 308 | el.style.height = surfaceElement.clientHeight + 'px'; 309 | el.style.overflow = 'hidden'; 310 | el.style.position = 'absolute'; 311 | surfaceElement.appendChild(el); 312 | 313 | this.element_ = el; 314 | this.arcScaleX_ = 1; 315 | this.arcScaleY_ = 1; 316 | this.lineScale_ = 1; 317 | } 318 | 319 | var contextPrototype = CanvasRenderingContext2D_.prototype; 320 | contextPrototype.clearRect = function() { 321 | this.element_.innerHTML = ''; 322 | }; 323 | 324 | contextPrototype.beginPath = function() { 325 | // TODO: Branch current matrix so that save/restore has no effect 326 | // as per safari docs. 327 | this.currentPath_ = []; 328 | }; 329 | 330 | contextPrototype.moveTo = function(aX, aY) { 331 | var p = this.getCoords_(aX, aY); 332 | this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); 333 | this.currentX_ = p.x; 334 | this.currentY_ = p.y; 335 | }; 336 | 337 | contextPrototype.lineTo = function(aX, aY) { 338 | var p = this.getCoords_(aX, aY); 339 | this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); 340 | 341 | this.currentX_ = p.x; 342 | this.currentY_ = p.y; 343 | }; 344 | 345 | contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, 346 | aCP2x, aCP2y, 347 | aX, aY) { 348 | var p = this.getCoords_(aX, aY); 349 | var cp1 = this.getCoords_(aCP1x, aCP1y); 350 | var cp2 = this.getCoords_(aCP2x, aCP2y); 351 | bezierCurveTo(this, cp1, cp2, p); 352 | }; 353 | 354 | // Helper function that takes the already fixed cordinates. 355 | function bezierCurveTo(self, cp1, cp2, p) { 356 | self.currentPath_.push({ 357 | type: 'bezierCurveTo', 358 | cp1x: cp1.x, 359 | cp1y: cp1.y, 360 | cp2x: cp2.x, 361 | cp2y: cp2.y, 362 | x: p.x, 363 | y: p.y 364 | }); 365 | self.currentX_ = p.x; 366 | self.currentY_ = p.y; 367 | } 368 | 369 | contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { 370 | // the following is lifted almost directly from 371 | // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes 372 | 373 | var cp = this.getCoords_(aCPx, aCPy); 374 | var p = this.getCoords_(aX, aY); 375 | 376 | var cp1 = { 377 | x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), 378 | y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) 379 | }; 380 | var cp2 = { 381 | x: cp1.x + (p.x - this.currentX_) / 3.0, 382 | y: cp1.y + (p.y - this.currentY_) / 3.0 383 | }; 384 | 385 | bezierCurveTo(this, cp1, cp2, p); 386 | }; 387 | 388 | contextPrototype.arc = function(aX, aY, aRadius, 389 | aStartAngle, aEndAngle, aClockwise) { 390 | aRadius *= Z; 391 | var arcType = aClockwise ? 'at' : 'wa'; 392 | 393 | var xStart = aX + mc(aStartAngle) * aRadius - Z2; 394 | var yStart = aY + ms(aStartAngle) * aRadius - Z2; 395 | 396 | var xEnd = aX + mc(aEndAngle) * aRadius - Z2; 397 | var yEnd = aY + ms(aEndAngle) * aRadius - Z2; 398 | 399 | // IE won't render arches drawn counter clockwise if xStart == xEnd. 400 | if (xStart == xEnd && !aClockwise) { 401 | xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something 402 | // that can be represented in binary 403 | } 404 | 405 | var p = this.getCoords_(aX, aY); 406 | var pStart = this.getCoords_(xStart, yStart); 407 | var pEnd = this.getCoords_(xEnd, yEnd); 408 | 409 | this.currentPath_.push({type: arcType, 410 | x: p.x, 411 | y: p.y, 412 | radius: aRadius, 413 | xStart: pStart.x, 414 | yStart: pStart.y, 415 | xEnd: pEnd.x, 416 | yEnd: pEnd.y}); 417 | 418 | }; 419 | 420 | contextPrototype.rect = function(aX, aY, aWidth, aHeight) { 421 | this.moveTo(aX, aY); 422 | this.lineTo(aX + aWidth, aY); 423 | this.lineTo(aX + aWidth, aY + aHeight); 424 | this.lineTo(aX, aY + aHeight); 425 | this.closePath(); 426 | }; 427 | 428 | contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { 429 | var oldPath = this.currentPath_; 430 | this.beginPath(); 431 | 432 | this.moveTo(aX, aY); 433 | this.lineTo(aX + aWidth, aY); 434 | this.lineTo(aX + aWidth, aY + aHeight); 435 | this.lineTo(aX, aY + aHeight); 436 | this.closePath(); 437 | this.stroke(); 438 | 439 | this.currentPath_ = oldPath; 440 | }; 441 | 442 | contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { 443 | var oldPath = this.currentPath_; 444 | this.beginPath(); 445 | 446 | this.moveTo(aX, aY); 447 | this.lineTo(aX + aWidth, aY); 448 | this.lineTo(aX + aWidth, aY + aHeight); 449 | this.lineTo(aX, aY + aHeight); 450 | this.closePath(); 451 | this.fill(); 452 | 453 | this.currentPath_ = oldPath; 454 | }; 455 | 456 | contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { 457 | var gradient = new CanvasGradient_('gradient'); 458 | gradient.x0_ = aX0; 459 | gradient.y0_ = aY0; 460 | gradient.x1_ = aX1; 461 | gradient.y1_ = aY1; 462 | return gradient; 463 | }; 464 | 465 | contextPrototype.createRadialGradient = function(aX0, aY0, aR0, 466 | aX1, aY1, aR1) { 467 | var gradient = new CanvasGradient_('gradientradial'); 468 | gradient.x0_ = aX0; 469 | gradient.y0_ = aY0; 470 | gradient.r0_ = aR0; 471 | gradient.x1_ = aX1; 472 | gradient.y1_ = aY1; 473 | gradient.r1_ = aR1; 474 | return gradient; 475 | }; 476 | 477 | contextPrototype.drawImage = function(image, var_args) { 478 | var dx, dy, dw, dh, sx, sy, sw, sh; 479 | 480 | // to find the original width we overide the width and height 481 | var oldRuntimeWidth = image.runtimeStyle.width; 482 | var oldRuntimeHeight = image.runtimeStyle.height; 483 | image.runtimeStyle.width = 'auto'; 484 | image.runtimeStyle.height = 'auto'; 485 | 486 | // get the original size 487 | var w = image.width; 488 | var h = image.height; 489 | 490 | // and remove overides 491 | image.runtimeStyle.width = oldRuntimeWidth; 492 | image.runtimeStyle.height = oldRuntimeHeight; 493 | 494 | if (arguments.length == 3) { 495 | dx = arguments[1]; 496 | dy = arguments[2]; 497 | sx = sy = 0; 498 | sw = dw = w; 499 | sh = dh = h; 500 | } else if (arguments.length == 5) { 501 | dx = arguments[1]; 502 | dy = arguments[2]; 503 | dw = arguments[3]; 504 | dh = arguments[4]; 505 | sx = sy = 0; 506 | sw = w; 507 | sh = h; 508 | } else if (arguments.length == 9) { 509 | sx = arguments[1]; 510 | sy = arguments[2]; 511 | sw = arguments[3]; 512 | sh = arguments[4]; 513 | dx = arguments[5]; 514 | dy = arguments[6]; 515 | dw = arguments[7]; 516 | dh = arguments[8]; 517 | } else { 518 | throw Error('Invalid number of arguments'); 519 | } 520 | 521 | var d = this.getCoords_(dx, dy); 522 | 523 | var w2 = sw / 2; 524 | var h2 = sh / 2; 525 | 526 | var vmlStr = []; 527 | 528 | var W = 10; 529 | var H = 10; 530 | 531 | // For some reason that I've now forgotten, using divs didn't work 532 | vmlStr.push(' ' , 571 | '', 579 | ''); 580 | 581 | this.element_.insertAdjacentHTML('BeforeEnd', 582 | vmlStr.join('')); 583 | }; 584 | 585 | contextPrototype.stroke = function(aFill) { 586 | var lineStr = []; 587 | var lineOpen = false; 588 | var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); 589 | var color = a.color; 590 | var opacity = a.alpha * this.globalAlpha; 591 | 592 | var W = 10; 593 | var H = 10; 594 | 595 | lineStr.push(''); 662 | 663 | if (!aFill) { 664 | var lineWidth = this.lineScale_ * this.lineWidth; 665 | 666 | // VML cannot correctly render a line if the width is less than 1px. 667 | // In that case, we dilute the color to make the line look thinner. 668 | if (lineWidth < 1) { 669 | opacity *= lineWidth; 670 | } 671 | 672 | lineStr.push( 673 | '' 680 | ); 681 | } else if (typeof this.fillStyle == 'object') { 682 | var fillStyle = this.fillStyle; 683 | var angle = 0; 684 | var focus = {x: 0, y: 0}; 685 | 686 | // additional offset 687 | var shift = 0; 688 | // scale factor for offset 689 | var expansion = 1; 690 | 691 | if (fillStyle.type_ == 'gradient') { 692 | var x0 = fillStyle.x0_ / this.arcScaleX_; 693 | var y0 = fillStyle.y0_ / this.arcScaleY_; 694 | var x1 = fillStyle.x1_ / this.arcScaleX_; 695 | var y1 = fillStyle.y1_ / this.arcScaleY_; 696 | var p0 = this.getCoords_(x0, y0); 697 | var p1 = this.getCoords_(x1, y1); 698 | var dx = p1.x - p0.x; 699 | var dy = p1.y - p0.y; 700 | angle = Math.atan2(dx, dy) * 180 / Math.PI; 701 | 702 | // The angle should be a non-negative number. 703 | if (angle < 0) { 704 | angle += 360; 705 | } 706 | 707 | // Very small angles produce an unexpected result because they are 708 | // converted to a scientific notation string. 709 | if (angle < 1e-6) { 710 | angle = 0; 711 | } 712 | } else { 713 | var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_); 714 | var width = max.x - min.x; 715 | var height = max.y - min.y; 716 | focus = { 717 | x: (p0.x - min.x) / width, 718 | y: (p0.y - min.y) / height 719 | }; 720 | 721 | width /= this.arcScaleX_ * Z; 722 | height /= this.arcScaleY_ * Z; 723 | var dimension = m.max(width, height); 724 | shift = 2 * fillStyle.r0_ / dimension; 725 | expansion = 2 * fillStyle.r1_ / dimension - shift; 726 | } 727 | 728 | // We need to sort the color stops in ascending order by offset, 729 | // otherwise IE won't interpret it correctly. 730 | var stops = fillStyle.colors_; 731 | stops.sort(function(cs1, cs2) { 732 | return cs1.offset - cs2.offset; 733 | }); 734 | 735 | var length = stops.length; 736 | var color1 = stops[0].color; 737 | var color2 = stops[length - 1].color; 738 | var opacity1 = stops[0].alpha * this.globalAlpha; 739 | var opacity2 = stops[length - 1].alpha * this.globalAlpha; 740 | 741 | var colors = []; 742 | for (var i = 0; i < length; i++) { 743 | var stop = stops[i]; 744 | colors.push(stop.offset * expansion + shift + ' ' + stop.color); 745 | } 746 | 747 | // When colors attribute is used, the meanings of opacity and o:opacity2 748 | // are reversed. 749 | lineStr.push(''); 758 | } else { 759 | lineStr.push(''); 761 | } 762 | 763 | lineStr.push(''); 764 | 765 | this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); 766 | }; 767 | 768 | contextPrototype.fill = function() { 769 | this.stroke(true); 770 | } 771 | 772 | contextPrototype.closePath = function() { 773 | this.currentPath_.push({type: 'close'}); 774 | }; 775 | 776 | /** 777 | * @private 778 | */ 779 | contextPrototype.getCoords_ = function(aX, aY) { 780 | var m = this.m_; 781 | return { 782 | x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, 783 | y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 784 | } 785 | }; 786 | 787 | contextPrototype.save = function() { 788 | var o = {}; 789 | copyState(this, o); 790 | this.aStack_.push(o); 791 | this.mStack_.push(this.m_); 792 | this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); 793 | }; 794 | 795 | contextPrototype.restore = function() { 796 | copyState(this.aStack_.pop(), this); 797 | this.m_ = this.mStack_.pop(); 798 | }; 799 | 800 | function matrixIsFinite(m) { 801 | for (var j = 0; j < 3; j++) { 802 | for (var k = 0; k < 2; k++) { 803 | if (!isFinite(m[j][k]) || isNaN(m[j][k])) { 804 | return false; 805 | } 806 | } 807 | } 808 | return true; 809 | } 810 | 811 | function setM(ctx, m, updateLineScale) { 812 | if (!matrixIsFinite(m)) { 813 | return; 814 | } 815 | ctx.m_ = m; 816 | 817 | if (updateLineScale) { 818 | // Get the line scale. 819 | // Determinant of this.m_ means how much the area is enlarged by the 820 | // transformation. So its square root can be used as a scale factor 821 | // for width. 822 | var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; 823 | ctx.lineScale_ = sqrt(abs(det)); 824 | } 825 | } 826 | 827 | contextPrototype.translate = function(aX, aY) { 828 | var m1 = [ 829 | [1, 0, 0], 830 | [0, 1, 0], 831 | [aX, aY, 1] 832 | ]; 833 | 834 | setM(this, matrixMultiply(m1, this.m_), false); 835 | }; 836 | 837 | contextPrototype.rotate = function(aRot) { 838 | var c = mc(aRot); 839 | var s = ms(aRot); 840 | 841 | var m1 = [ 842 | [c, s, 0], 843 | [-s, c, 0], 844 | [0, 0, 1] 845 | ]; 846 | 847 | setM(this, matrixMultiply(m1, this.m_), false); 848 | }; 849 | 850 | contextPrototype.scale = function(aX, aY) { 851 | this.arcScaleX_ *= aX; 852 | this.arcScaleY_ *= aY; 853 | var m1 = [ 854 | [aX, 0, 0], 855 | [0, aY, 0], 856 | [0, 0, 1] 857 | ]; 858 | 859 | setM(this, matrixMultiply(m1, this.m_), true); 860 | }; 861 | 862 | contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) { 863 | var m1 = [ 864 | [m11, m12, 0], 865 | [m21, m22, 0], 866 | [dx, dy, 1] 867 | ]; 868 | 869 | setM(this, matrixMultiply(m1, this.m_), true); 870 | }; 871 | 872 | contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) { 873 | var m = [ 874 | [m11, m12, 0], 875 | [m21, m22, 0], 876 | [dx, dy, 1] 877 | ]; 878 | 879 | setM(this, m, true); 880 | }; 881 | 882 | /******** STUBS ********/ 883 | contextPrototype.clip = function() { 884 | // TODO: Implement 885 | }; 886 | 887 | contextPrototype.arcTo = function() { 888 | // TODO: Implement 889 | }; 890 | 891 | contextPrototype.createPattern = function() { 892 | return new CanvasPattern_; 893 | }; 894 | 895 | // Gradient / Pattern Stubs 896 | function CanvasGradient_(aType) { 897 | this.type_ = aType; 898 | this.x0_ = 0; 899 | this.y0_ = 0; 900 | this.r0_ = 0; 901 | this.x1_ = 0; 902 | this.y1_ = 0; 903 | this.r1_ = 0; 904 | this.colors_ = []; 905 | } 906 | 907 | CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { 908 | aColor = processStyle(aColor); 909 | this.colors_.push({offset: aOffset, 910 | color: aColor.color, 911 | alpha: aColor.alpha}); 912 | }; 913 | 914 | function CanvasPattern_() {} 915 | 916 | // set up externs 917 | G_vmlCanvasManager = G_vmlCanvasManager_; 918 | CanvasRenderingContext2D = CanvasRenderingContext2D_; 919 | CanvasGradient = CanvasGradient_; 920 | CanvasPattern = CanvasPattern_; 921 | 922 | })(); 923 | 924 | } // if 925 | -------------------------------------------------------------------------------- /mootools/mootools-core-1.3.2.js: -------------------------------------------------------------------------------- 1 | /* 2 | --- 3 | MooTools: the javascript framework 4 | 5 | web build: 6 | - http://mootools.net/core/a658f28c6a59e22dfb2d2b840a39f6fa 7 | 8 | packager build: 9 | - packager build Core/Class Core/Class.Extras Core/Element.Dimensions Core/DOMReady 10 | 11 | copyrights: 12 | - [MooTools](http://mootools.net) 13 | 14 | licenses: 15 | - [MIT License](http://mootools.net/license.txt) 16 | ... 17 | */ 18 | (function(){this.MooTools={version:"1.3.2",build:"c9f1ff10e9e7facb65e9481049ed1b450959d587"};var o=this.typeOf=function(i){if(i==null){return"null";}if(i.$family){return i.$family(); 19 | }if(i.nodeName){if(i.nodeType==1){return"element";}if(i.nodeType==3){return(/\S/).test(i.nodeValue)?"textnode":"whitespace";}}else{if(typeof i.length=="number"){if(i.callee){return"arguments"; 20 | }if("item" in i){return"collection";}}}return typeof i;};var j=this.instanceOf=function(t,i){if(t==null){return false;}var s=t.$constructor||t.constructor; 21 | while(s){if(s===i){return true;}s=s.parent;}return t instanceof i;};var f=this.Function;var p=true;for(var k in {toString:1}){p=null;}if(p){p=["hasOwnProperty","valueOf","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","constructor"]; 22 | }f.prototype.overloadSetter=function(s){var i=this;return function(u,t){if(u==null){return this;}if(s||typeof u!="string"){for(var v in u){i.call(this,v,u[v]); 23 | }if(p){for(var w=p.length;w--;){v=p[w];if(u.hasOwnProperty(v)){i.call(this,v,u[v]);}}}}else{i.call(this,u,t);}return this;};};f.prototype.overloadGetter=function(s){var i=this; 24 | return function(u){var v,t;if(s||typeof u!="string"){v=u;}else{if(arguments.length>1){v=arguments;}}if(v){t={};for(var w=0;w-1:this.indexOf(a)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim(); 59 | },camelCase:function(){return this.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(a){return("-"+a.charAt(0).toLowerCase()); 60 | });},capitalize:function(){return this.replace(/\b[a-z]/g,function(a){return a.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1"); 61 | },toInt:function(a){return parseInt(this,a||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(b){var a=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); 62 | return(a)?a.slice(1).hexToRgb(b):null;},rgbToHex:function(b){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHex(b):null;},substitute:function(a,b){return this.replace(b||(/\\?\{([^{}]+)\}/g),function(d,c){if(d.charAt(0)=="\\"){return d.slice(1); 63 | }return(a[c]!=null)?a[c]:"";});}});Function.extend({attempt:function(){for(var b=0,a=arguments.length;b1)?Array.slice(arguments,1):null; 65 | return function(){if(!b&&!arguments.length){return a.call(c);}if(b&&arguments.length){return a.apply(c,b.concat(Array.from(arguments)));}return a.apply(c,b||arguments); 66 | };},pass:function(b,c){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},delay:function(b,c,a){return setTimeout(this.pass((a==null?[]:a),c),b); 67 | },periodical:function(c,b,a){return setInterval(this.pass((a==null?[]:a),b),c);}});Number.implement({limit:function(b,a){return Math.min(a,Math.max(b,this)); 68 | },round:function(a){a=Math.pow(10,a||0).toFixed(a<0?-a:0);return Math.round(this*a)/a;},times:function(b,c){for(var a=0;a]*>([\s\S]*?)<\/script>/gi,function(r,s){e+=s+"\n"; 98 | return"";});if(p===true){o.exec(e);}else{if(typeOf(p)=="function"){p(e,q);}}return q;});o.extend({Document:this.Document,Window:this.Window,Element:this.Element,Event:this.Event}); 99 | this.Window=this.$constructor=new Type("Window",function(){});this.$family=Function.from("window").hide();Window.mirror(function(e,p){i[e]=p;});this.Document=k.$constructor=new Type("Document",function(){}); 100 | k.$family=Function.from("document").hide();Document.mirror(function(e,p){k[e]=p;});k.html=k.documentElement;if(!k.head){k.head=k.getElementsByTagName("head")[0]; 101 | }if(k.execCommand){try{k.execCommand("BackgroundImageCache",false,true);}catch(g){}}if(this.attachEvent&&!this.addEventListener){var d=function(){this.detachEvent("onunload",d); 102 | k.head=k.html=k.window=null;};this.attachEvent("onunload",d);}var m=Array.from;try{m(k.html.childNodes);}catch(g){Array.from=function(p){if(typeof p!="string"&&Type.isEnumerable(p)&&typeOf(p)!="array"){var e=p.length,q=new Array(e); 103 | while(e--){q[e]=p[e];}return q;}return m(p);};var l=Array.prototype,n=l.slice;["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice"].each(function(e){var p=l[e]; 104 | Array[e]=function(q){return p.apply(Array.from(q),n.call(arguments,1));};});}})();(function(){var k,n,l,g,a={},c={},m=/\\/g;var e=function(q,p){if(q==null){return null; 105 | }if(q.Slick===true){return q;}q=(""+q).replace(/^\s+|\s+$/g,"");g=!!p;var o=(g)?c:a;if(o[q]){return o[q];}k={Slick:true,expressions:[],raw:q,reverse:function(){return e(this.raw,true); 106 | }};n=-1;while(q!=(q=q.replace(j,b))){}k.length=k.expressions.length;return o[k.raw]=(g)?h(k):k;};var i=function(o){if(o==="!"){return" ";}else{if(o===" "){return"!"; 107 | }else{if((/^!/).test(o)){return o.replace(/^!/,"");}else{return"!"+o;}}}};var h=function(u){var r=u.expressions;for(var p=0;p+)\\s*|(\\s+)|(+|\\*)|\\#(+)|\\.(+)|\\[\\s*(+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)".replace(//,"["+f(">+~`!@$%^&={}\\;/g,"(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])").replace(//g,"(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])")); 111 | function b(x,s,D,z,r,C,q,B,A,y,u,F,G,v,p,w){if(s||n===-1){k.expressions[++n]=[];l=-1;if(s){return"";}}if(D||z||l===-1){D=D||" ";var t=k.expressions[n]; 112 | if(g&&t[l]){t[l].reverseCombinator=i(D);}t[++l]={combinator:D,tag:"*"};}var o=k.expressions[n][l];if(r){o.tag=r.replace(m,"");}else{if(C){o.id=C.replace(m,""); 113 | }else{if(q){q=q.replace(m,"");if(!o.classList){o.classList=[];}if(!o.classes){o.classes=[];}o.classList.push(q);o.classes.push({value:q,regexp:new RegExp("(^|\\s)"+f(q)+"(\\s|$)")}); 114 | }else{if(G){w=w||p;w=w?w.replace(m,""):null;if(!o.pseudos){o.pseudos=[];}o.pseudos.push({key:G.replace(m,""),value:w,type:F.length==1?"class":"element"}); 115 | }else{if(B){B=B.replace(m,"");u=(u||"").replace(m,"");var E,H;switch(A){case"^=":H=new RegExp("^"+f(u));break;case"$=":H=new RegExp(f(u)+"$");break;case"~=":H=new RegExp("(^|\\s)"+f(u)+"(\\s|$)"); 116 | break;case"|=":H=new RegExp("^"+f(u)+"(-|$)");break;case"=":E=function(I){return u==I;};break;case"*=":E=function(I){return I&&I.indexOf(u)>-1;};break; 117 | case"!=":E=function(I){return u!=I;};break;default:E=function(I){return !!I;};}if(u==""&&(/^[*$^]=$/).test(A)){E=function(){return false;};}if(!E){E=function(I){return I&&H.test(I); 118 | };}if(!o.attributes){o.attributes=[];}o.attributes.push({key:B,operator:A,value:u,test:E});}}}}}return"";}var d=(this.Slick||{});d.parse=function(o){return e(o); 119 | };d.escapeRegExp=f;if(!this.Slick){this.Slick=d;}}).apply((typeof exports!="undefined")?exports:this);(function(){var j={},l={},b=Object.prototype.toString; 120 | j.isNativeCode=function(c){return(/\{\s*\[native code\]\s*\}/).test(""+c);};j.isXML=function(c){return(!!c.xmlVersion)||(!!c.xml)||(b.call(c)=="[object XMLDocument]")||(c.nodeType==9&&c.documentElement.nodeName!="HTML"); 121 | };j.setDocument=function(w){var t=w.nodeType;if(t==9){}else{if(t){w=w.ownerDocument;}else{if(w.navigator){w=w.document;}else{return;}}}if(this.document===w){return; 122 | }this.document=w;var y=w.documentElement,u=this.getUIDXML(y),o=l[u],A;if(o){for(A in o){this[A]=o[A];}return;}o=l[u]={};o.root=y;o.isXMLDocument=this.isXML(w); 123 | o.brokenStarGEBTN=o.starSelectsClosedQSA=o.idGetsName=o.brokenMixedCaseQSA=o.brokenGEBCN=o.brokenCheckedQSA=o.brokenEmptyAttributeQSA=o.isHTMLDocument=o.nativeMatchesSelector=false; 124 | var m,n,x,q,r;var s,c="slick_uniqueid";var z=w.createElement("div");var p=w.body||w.getElementsByTagName("body")[0]||y;p.appendChild(z);try{z.innerHTML=''; 125 | o.isHTMLDocument=!!w.getElementById(c);}catch(v){}if(o.isHTMLDocument){z.style.display="none";z.appendChild(w.createComment(""));n=(z.getElementsByTagName("*").length>1); 126 | try{z.innerHTML="foo";s=z.getElementsByTagName("*");m=(s&&!!s.length&&s[0].nodeName.charAt(0)=="/");}catch(v){}o.brokenStarGEBTN=n||m;try{z.innerHTML=''; 127 | o.idGetsName=w.getElementById(c)===z.firstChild;}catch(v){}if(z.getElementsByClassName){try{z.innerHTML='';z.getElementsByClassName("b").length; 128 | z.firstChild.className="b";q=(z.getElementsByClassName("b").length!=2);}catch(v){}try{z.innerHTML='';x=(z.getElementsByClassName("a").length!=2); 129 | }catch(v){}o.brokenGEBCN=q||x;}if(z.querySelectorAll){try{z.innerHTML="foo";s=z.querySelectorAll("*");o.starSelectsClosedQSA=(s&&!!s.length&&s[0].nodeName.charAt(0)=="/"); 130 | }catch(v){}try{z.innerHTML='';o.brokenMixedCaseQSA=!z.querySelectorAll(".MiX").length;}catch(v){}try{z.innerHTML=''; 131 | o.brokenCheckedQSA=(z.querySelectorAll(":checked").length==0);}catch(v){}try{z.innerHTML='';o.brokenEmptyAttributeQSA=(z.querySelectorAll('[class*=""]').length!=0); 132 | }catch(v){}}try{z.innerHTML='
';r=(z.firstChild.getAttribute("action")!="s");}catch(v){}o.nativeMatchesSelector=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector; 133 | if(o.nativeMatchesSelector){try{o.nativeMatchesSelector.call(y,":slick");o.nativeMatchesSelector=null;}catch(v){}}}try{y.slick_expando=1;delete y.slick_expando; 134 | o.getUID=this.getUIDHTML;}catch(v){o.getUID=this.getUIDXML;}p.removeChild(z);z=s=p=null;o.getAttribute=(o.isHTMLDocument&&r)?function(D,B){var E=this.attributeGetters[B]; 135 | if(E){return E.call(D);}var C=D.getAttributeNode(B);return(C)?C.nodeValue:null;}:function(C,B){var D=this.attributeGetters[B];return(D)?D.call(C):C.getAttribute(B); 136 | };o.hasAttribute=(y&&this.isNativeCode(y.hasAttribute))?function(C,B){return C.hasAttribute(B);}:function(C,B){C=C.getAttributeNode(B);return !!(C&&(C.specified||C.nodeValue)); 137 | };o.contains=(y&&this.isNativeCode(y.contains))?function(B,C){return B.contains(C);}:(y&&y.compareDocumentPosition)?function(B,C){return B===C||!!(B.compareDocumentPosition(C)&16); 138 | }:function(B,C){if(C){do{if(C===B){return true;}}while((C=C.parentNode));}return false;};o.documentSorter=(y.compareDocumentPosition)?function(C,B){if(!C.compareDocumentPosition||!B.compareDocumentPosition){return 0; 139 | }return C.compareDocumentPosition(B)&4?-1:C===B?0:1;}:("sourceIndex" in y)?function(C,B){if(!C.sourceIndex||!B.sourceIndex){return 0;}return C.sourceIndex-B.sourceIndex; 140 | }:(w.createRange)?function(E,C){if(!E.ownerDocument||!C.ownerDocument){return 0;}var D=E.ownerDocument.createRange(),B=C.ownerDocument.createRange();D.setStart(E,0); 141 | D.setEnd(E,0);B.setStart(C,0);B.setEnd(C,0);return D.compareBoundaryPoints(Range.START_TO_END,B);}:null;y=null;for(A in o){this[A]=o[A];}};var e=/^([#.]?)((?:[\w-]+|\*))$/,g=/\[.+[*$^]=(?:""|'')?\]/,f={}; 142 | j.search=function(U,z,H,s){var p=this.found=(s)?null:(H||[]);if(!U){return p;}else{if(U.navigator){U=U.document;}else{if(!U.nodeType){return p;}}}var F,O,V=this.uniques={},I=!!(H&&H.length),y=(U.nodeType==9); 143 | if(this.document!==(y?U:U.ownerDocument)){this.setDocument(U);}if(I){for(O=p.length;O--;){V[this.getUID(p[O])]=true;}}if(typeof z=="string"){var r=z.match(e); 144 | simpleSelectors:if(r){var u=r[1],v=r[2],A,E;if(!u){if(v=="*"&&this.brokenStarGEBTN){break simpleSelectors;}E=U.getElementsByTagName(v);if(s){return E[0]||null; 145 | }for(O=0;A=E[O++];){if(!(I&&V[this.getUID(A)])){p.push(A);}}}else{if(u=="#"){if(!this.isHTMLDocument||!y){break simpleSelectors;}A=U.getElementById(v); 146 | if(!A){return p;}if(this.idGetsName&&A.getAttributeNode("id").nodeValue!=v){break simpleSelectors;}if(s){return A||null;}if(!(I&&V[this.getUID(A)])){p.push(A); 147 | }}else{if(u=="."){if(!this.isHTMLDocument||((!U.getElementsByClassName||this.brokenGEBCN)&&U.querySelectorAll)){break simpleSelectors;}if(U.getElementsByClassName&&!this.brokenGEBCN){E=U.getElementsByClassName(v); 148 | if(s){return E[0]||null;}for(O=0;A=E[O++];){if(!(I&&V[this.getUID(A)])){p.push(A);}}}else{var T=new RegExp("(^|\\s)"+d.escapeRegExp(v)+"(\\s|$)");E=U.getElementsByTagName("*"); 149 | for(O=0;A=E[O++];){className=A.className;if(!(className&&T.test(className))){continue;}if(s){return A;}if(!(I&&V[this.getUID(A)])){p.push(A);}}}}}}if(I){this.sort(p); 150 | }return(s)?null:p;}querySelector:if(U.querySelectorAll){if(!this.isHTMLDocument||f[z]||this.brokenMixedCaseQSA||(this.brokenCheckedQSA&&z.indexOf(":checked")>-1)||(this.brokenEmptyAttributeQSA&&g.test(z))||(!y&&z.indexOf(",")>-1)||d.disableQSA){break querySelector; 151 | }var S=z,x=U;if(!y){var C=x.getAttribute("id"),t="slickid__";x.setAttribute("id",t);S="#"+t+" "+S;U=x.parentNode;}try{if(s){return U.querySelector(S)||null; 152 | }else{E=U.querySelectorAll(S);}}catch(Q){f[z]=1;break querySelector;}finally{if(!y){if(C){x.setAttribute("id",C);}else{x.removeAttribute("id");}U=x;}}if(this.starSelectsClosedQSA){for(O=0; 153 | A=E[O++];){if(A.nodeName>"@"&&!(I&&V[this.getUID(A)])){p.push(A);}}}else{for(O=0;A=E[O++];){if(!(I&&V[this.getUID(A)])){p.push(A);}}}if(I){this.sort(p); 154 | }return p;}F=this.Slick.parse(z);if(!F.length){return p;}}else{if(z==null){return p;}else{if(z.Slick){F=z;}else{if(this.contains(U.documentElement||U,z)){(p)?p.push(z):p=z; 155 | return p;}else{return p;}}}}this.posNTH={};this.posNTHLast={};this.posNTHType={};this.posNTHTypeLast={};this.push=(!I&&(s||(F.length==1&&F.expressions[0].length==1)))?this.pushArray:this.pushUID; 156 | if(p==null){p=[];}var M,L,K;var B,J,D,c,q,G,W;var N,P,o,w,R=F.expressions;search:for(O=0;(P=R[O]);O++){for(M=0;(o=P[M]);M++){B="combinator:"+o.combinator; 157 | if(!this[B]){continue search;}J=(this.isXMLDocument)?o.tag:o.tag.toUpperCase();D=o.id;c=o.classList;q=o.classes;G=o.attributes;W=o.pseudos;w=(M===(P.length-1)); 158 | this.bitUniques={};if(w){this.uniques=V;this.found=p;}else{this.uniques={};this.found=[];}if(M===0){this[B](U,J,D,q,G,W,c);if(s&&w&&p.length){break search; 159 | }}else{if(s&&w){for(L=0,K=N.length;L1)){this.sort(p);}return(s)?(p[0]||null):p;};j.uidx=1;j.uidk="slick-uniqueid";j.getUIDXML=function(m){var c=m.getAttribute(this.uidk); 161 | if(!c){c=this.uidx++;m.setAttribute(this.uidk,c);}return c;};j.getUIDHTML=function(c){return c.uniqueNumber||(c.uniqueNumber=this.uidx++);};j.sort=function(c){if(!this.documentSorter){return c; 162 | }c.sort(this.documentSorter);return c;};j.cacheNTH={};j.matchNTH=/^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;j.parseNTHArgument=function(p){var n=p.match(this.matchNTH); 163 | if(!n){return false;}var o=n[2]||false;var m=n[1]||1;if(m=="-"){m=-1;}var c=+n[3]||0;n=(o=="n")?{a:m,b:c}:(o=="odd")?{a:2,b:1}:(o=="even")?{a:2,b:0}:{a:0,b:m}; 164 | return(this.cacheNTH[p]=n);};j.createNTHPseudo=function(o,m,c,n){return function(r,p){var t=this.getUID(r);if(!this[c][t]){var z=r.parentNode;if(!z){return false; 165 | }var q=z[o],s=1;if(n){var y=r.nodeName;do{if(q.nodeName!=y){continue;}this[c][this.getUID(q)]=s++;}while((q=q[m]));}else{do{if(q.nodeType!=1){continue; 166 | }this[c][this.getUID(q)]=s++;}while((q=q[m]));}}p=p||"n";var u=this.cacheNTH[p]||this.parseNTHArgument(p);if(!u){return false;}var x=u.a,w=u.b,v=this[c][t]; 167 | if(x==0){return w==v;}if(x>0){if(v":function(o,c,q,n,m,p){if((o=o.firstChild)){do{if(o.nodeType==1){this.push(o,c,q,n,m,p); 182 | }}while((o=o.nextSibling));}},"+":function(o,c,q,n,m,p){while((o=o.nextSibling)){if(o.nodeType==1){this.push(o,c,q,n,m,p);break;}}},"^":function(o,c,q,n,m,p){o=o.firstChild; 183 | if(o){if(o.nodeType==1){this.push(o,c,q,n,m,p);}else{this["combinator:+"](o,c,q,n,m,p);}}},"~":function(p,c,r,o,m,q){while((p=p.nextSibling)){if(p.nodeType!=1){continue; 184 | }var n=this.getUID(p);if(this.bitUniques[n]){break;}this.bitUniques[n]=true;this.push(p,c,r,o,m,q);}},"++":function(o,c,q,n,m,p){this["combinator:+"](o,c,q,n,m,p); 185 | this["combinator:!+"](o,c,q,n,m,p);},"~~":function(o,c,q,n,m,p){this["combinator:~"](o,c,q,n,m,p);this["combinator:!~"](o,c,q,n,m,p);},"!":function(o,c,q,n,m,p){while((o=o.parentNode)){if(o!==this.document){this.push(o,c,q,n,m,p); 186 | }}},"!>":function(o,c,q,n,m,p){o=o.parentNode;if(o!==this.document){this.push(o,c,q,n,m,p);}},"!+":function(o,c,q,n,m,p){while((o=o.previousSibling)){if(o.nodeType==1){this.push(o,c,q,n,m,p); 187 | break;}}},"!^":function(o,c,q,n,m,p){o=o.lastChild;if(o){if(o.nodeType==1){this.push(o,c,q,n,m,p);}else{this["combinator:!+"](o,c,q,n,m,p);}}},"!~":function(p,c,r,o,m,q){while((p=p.previousSibling)){if(p.nodeType!=1){continue; 188 | }var n=this.getUID(p);if(this.bitUniques[n]){break;}this.bitUniques[n]=true;this.push(p,c,r,o,m,q);}}};for(var h in i){j["combinator:"+h]=i[h];}var k={empty:function(c){var m=c.firstChild; 189 | return !(m&&m.nodeType==1)&&!(c.innerText||c.textContent||"").length;},not:function(c,m){return !this.matchNode(c,m);},contains:function(c,m){return(c.innerText||c.textContent||"").indexOf(m)>-1; 190 | },"first-child":function(c){while((c=c.previousSibling)){if(c.nodeType==1){return false;}}return true;},"last-child":function(c){while((c=c.nextSibling)){if(c.nodeType==1){return false; 191 | }}return true;},"only-child":function(n){var m=n;while((m=m.previousSibling)){if(m.nodeType==1){return false;}}var c=n;while((c=c.nextSibling)){if(c.nodeType==1){return false; 192 | }}return true;},"nth-child":j.createNTHPseudo("firstChild","nextSibling","posNTH"),"nth-last-child":j.createNTHPseudo("lastChild","previousSibling","posNTHLast"),"nth-of-type":j.createNTHPseudo("firstChild","nextSibling","posNTHType",true),"nth-last-of-type":j.createNTHPseudo("lastChild","previousSibling","posNTHTypeLast",true),index:function(m,c){return this["pseudo:nth-child"](m,""+c+1); 193 | },even:function(c){return this["pseudo:nth-child"](c,"2n");},odd:function(c){return this["pseudo:nth-child"](c,"2n+1");},"first-of-type":function(c){var m=c.nodeName; 194 | while((c=c.previousSibling)){if(c.nodeName==m){return false;}}return true;},"last-of-type":function(c){var m=c.nodeName;while((c=c.nextSibling)){if(c.nodeName==m){return false; 195 | }}return true;},"only-of-type":function(n){var m=n,o=n.nodeName;while((m=m.previousSibling)){if(m.nodeName==o){return false;}}var c=n;while((c=c.nextSibling)){if(c.nodeName==o){return false; 196 | }}return true;},enabled:function(c){return !c.disabled;},disabled:function(c){return c.disabled;},checked:function(c){return c.checked||c.selected;},focus:function(c){return this.isHTMLDocument&&this.document.activeElement===c&&(c.href||c.type||this.hasAttribute(c,"tabindex")); 197 | },root:function(c){return(c===this.root);},selected:function(c){return c.selected;}};for(var a in k){j["pseudo:"+a]=k[a];}j.attributeGetters={"class":function(){return this.getAttribute("class")||this.className; 198 | },"for":function(){return("htmlFor" in this)?this.htmlFor:this.getAttribute("for");},href:function(){return("href" in this)?this.getAttribute("href",2):this.getAttribute("href"); 199 | },style:function(){return(this.style)?this.style.cssText:this.getAttribute("style");},tabindex:function(){var c=this.getAttributeNode("tabindex");return(c&&c.specified)?c.nodeValue:null; 200 | },type:function(){return this.getAttribute("type");}};var d=j.Slick=(this.Slick||{});d.version="1.1.5";d.search=function(m,n,c){return j.search(m,n,c); 201 | };d.find=function(c,m){return j.search(c,m,null,true);};d.contains=function(c,m){j.setDocument(c);return j.contains(c,m);};d.getAttribute=function(m,c){return j.getAttribute(m,c); 202 | };d.match=function(m,c){if(!(m&&c)){return false;}if(!c||c===m){return true;}j.setDocument(m);return j.matchNode(m,c);};d.defineAttributeGetter=function(c,m){j.attributeGetters[c]=m; 203 | return this;};d.lookupAttributeGetter=function(c){return j.attributeGetters[c];};d.definePseudo=function(c,m){j["pseudo:"+c]=function(o,n){return m.call(o,n); 204 | };return this;};d.lookupPseudo=function(c){var m=j["pseudo:"+c];if(m){return function(n){return m.call(this,n);};}return null;};d.override=function(m,c){j.override(m,c); 205 | return this;};d.isXML=j.isXML;d.uidOf=function(c){return j.getUIDHTML(c);};if(!this.Slick){this.Slick=d;}}).apply((typeof exports!="undefined")?exports:this); 206 | var Element=function(b,g){var h=Element.Constructors[b];if(h){return h(g);}if(typeof b!="string"){return document.id(b).set(g);}if(!g){g={};}if(!(/^[\w-]+$/).test(b)){var e=Slick.parse(b).expressions[0][0]; 207 | b=(e.tag=="*")?"div":e.tag;if(e.id&&g.id==null){g.id=e.id;}var d=e.attributes;if(d){for(var f=0,c=d.length;f=this.length){delete this[e--];}return this; 222 | }.protect());}Elements.implement(Array.prototype);Array.mirror(Elements);var f;try{var a=document.createElement("");f=(a.name=="x");}catch(c){}var d=function(e){return(""+e).replace(/&/g,"&").replace(/"/g,"""); 223 | };Document.implement({newElement:function(e,h){if(h&&h.checked!=null){h.defaultChecked=h.checked;}if(f&&h){e="<"+e;if(h.name){e+=' name="'+d(h.name)+'"'; 224 | }if(h.type){e+=' type="'+d(h.type)+'"';}e+=">";delete h.name;delete h.type;}return this.id(this.createElement(e)).set(h);}});})();Document.implement({newTextNode:function(a){return this.createTextNode(a); 225 | },getDocument:function(){return this;},getWindow:function(){return this.window;},id:(function(){var a={string:function(d,c,b){d=Slick.find(b,"#"+d.replace(/(\W)/g,"\\$1")); 226 | return(d)?a.element(d,c):null;},element:function(b,c){$uid(b);if(!c&&!b.$family&&!(/^(?:object|embed)$/i).test(b.tagName)){Object.append(b,Element.Prototype); 227 | }return b;},object:function(c,d,b){if(c.toElement){return a.element(c.toElement(b),d);}return null;}};a.textnode=a.whitespace=a.window=a.document=function(b){return b; 228 | };return function(c,e,d){if(c&&c.$family&&c.uid){return c;}var b=typeOf(c);return(a[b])?a[b](c,e,d||document):null;};})()});if(window.$==null){Window.implement("$",function(a,b){return document.id(a,b,this.document); 229 | });}Window.implement({getDocument:function(){return this.document;},getWindow:function(){return this;}});[Document,Element].invoke("implement",{getElements:function(a){return Slick.search(this,a,new Elements); 230 | },getElement:function(a){return document.id(Slick.find(this,a));}});if(window.$$==null){Window.implement("$$",function(a){if(arguments.length==1){if(typeof a=="string"){return Slick.search(this.document,a,new Elements); 231 | }else{if(Type.isEnumerable(a)){return new Elements(a);}}}return new Elements(arguments);});}(function(){var k={},i={};var n={input:"checked",option:"selected",textarea:"value"}; 232 | var e=function(p){return(i[p]||(i[p]={}));};var j=function(q){var p=q.uid;if(q.removeEvents){q.removeEvents();}if(q.clearAttributes){q.clearAttributes(); 233 | }if(p!=null){delete k[p];delete i[p];}return q;};var o=["defaultValue","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"]; 234 | var d=["compact","nowrap","ismap","declare","noshade","checked","disabled","readOnly","multiple","selected","noresize","defer","defaultChecked"];var g={html:"innerHTML","class":"className","for":"htmlFor",text:(function(){var p=document.createElement("div"); 235 | return(p.textContent==null)?"innerText":"textContent";})()};var m=["type"];var h=["value","defaultValue"];var l=/^(?:href|src|usemap)$/i;d=d.associate(d); 236 | o=o.associate(o.map(String.toLowerCase));m=m.associate(m);Object.append(g,h.associate(h));var c={before:function(q,p){var r=p.parentNode;if(r){r.insertBefore(q,p); 237 | }},after:function(q,p){var r=p.parentNode;if(r){r.insertBefore(q,p.nextSibling);}},bottom:function(q,p){p.appendChild(q);},top:function(q,p){p.insertBefore(q,p.firstChild); 238 | }};c.inside=c.bottom;var b=function(s,r){if(!s){return r;}s=Object.clone(Slick.parse(s));var q=s.expressions;for(var p=q.length;p--;){q[p][0].combinator=r; 239 | }return s;};Element.implement({set:function(r,q){var p=Element.Properties[r];(p&&p.set)?p.set.call(this,q):this.setProperty(r,q);}.overloadSetter(),get:function(q){var p=Element.Properties[q]; 240 | return(p&&p.get)?p.get.apply(this):this.getProperty(q);}.overloadGetter(),erase:function(q){var p=Element.Properties[q];(p&&p.erase)?p.erase.apply(this):this.removeProperty(q); 241 | return this;},setProperty:function(q,r){q=o[q]||q;if(r==null){return this.removeProperty(q);}var p=g[q];(p)?this[p]=r:(d[q])?this[q]=!!r:this.setAttribute(q,""+r); 242 | return this;},setProperties:function(p){for(var q in p){this.setProperty(q,p[q]);}return this;},getProperty:function(q){q=o[q]||q;var p=g[q]||m[q];return(p)?this[p]:(d[q])?!!this[q]:(l.test(q)?this.getAttribute(q,2):(p=this.getAttributeNode(q))?p.nodeValue:null)||null; 243 | },getProperties:function(){var p=Array.from(arguments);return p.map(this.getProperty,this).associate(p);},removeProperty:function(q){q=o[q]||q;var p=g[q]; 244 | (p)?this[p]="":(d[q])?this[q]=false:this.removeAttribute(q);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this; 245 | },hasClass:function(p){return this.className.clean().contains(p," ");},addClass:function(p){if(!this.hasClass(p)){this.className=(this.className+" "+p).clean(); 246 | }return this;},removeClass:function(p){this.className=this.className.replace(new RegExp("(^|\\s)"+p+"(?:\\s|$)"),"$1");return this;},toggleClass:function(p,q){if(q==null){q=!this.hasClass(p); 247 | }return(q)?this.addClass(p):this.removeClass(p);},adopt:function(){var s=this,p,u=Array.flatten(arguments),t=u.length;if(t>1){s=p=document.createDocumentFragment(); 248 | }for(var r=0;r"))[0]);},getLast:function(p){return document.id(Slick.search(this,b(p,">")).getLast()); 253 | },getParent:function(p){return document.id(Slick.find(this,b(p,"!")));},getParents:function(p){return Slick.search(this,b(p,"!"),new Elements);},getSiblings:function(p){return Slick.search(this,b(p,"~~"),new Elements); 254 | },getChildren:function(p){return Slick.search(this,b(p,">"),new Elements);},getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument; 255 | },getElementById:function(p){return document.id(Slick.find(this,"#"+(""+p).replace(/(\W)/g,"\\$1")));},getSelected:function(){this.selectedIndex;return new Elements(Array.from(this.options).filter(function(p){return p.selected; 256 | }));},toQueryString:function(){var p=[];this.getElements("input, select, textarea").each(function(r){var q=r.type;if(!r.name||r.disabled||q=="submit"||q=="reset"||q=="file"||q=="image"){return; 257 | }var s=(r.get("tag")=="select")?r.getSelected().map(function(t){return document.id(t).get("value");}):((q=="radio"||q=="checkbox")&&!r.checked)?null:r.get("value"); 258 | Array.from(s).each(function(t){if(typeof t!="undefined"){p.push(encodeURIComponent(r.name)+"="+encodeURIComponent(t));}});});return p.join("&");},destroy:function(){var p=j(this).getElementsByTagName("*"); 259 | Array.each(p,j);Element.dispose(this);return null;},empty:function(){Array.from(this.childNodes).each(Element.dispose);return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this; 260 | },match:function(p){return !p||Slick.match(this,p);}});var a=function(t,s,q){if(!q){t.setAttributeNode(document.createAttribute("id"));}if(t.clearAttributes){t.clearAttributes(); 261 | t.mergeAttributes(s);t.removeAttribute("uid");if(t.options){var u=t.options,p=s.options;for(var r=u.length;r--;){u[r].selected=p[r].selected;}}}var v=n[s.tagName.toLowerCase()]; 262 | if(v&&s[v]){t[v]=s[v];}};Element.implement("clone",function(r,p){r=r!==false;var w=this.cloneNode(r),q;if(r){var s=w.getElementsByTagName("*"),u=this.getElementsByTagName("*"); 263 | for(q=s.length;q--;){a(s[q],u[q],p);}}a(w,this,p);if(Browser.ie){var t=w.getElementsByTagName("object"),v=this.getElementsByTagName("object");for(q=t.length; 264 | q--;){t[q].outerHTML=v[q].outerHTML;}}return document.id(w);});var f={contains:function(p){return Slick.contains(this,p);}};if(!document.contains){Document.implement(f); 265 | }if(!document.createElement("div").contains){Element.implement(f);}[Element,Window,Document].invoke("implement",{addListener:function(s,r){if(s=="unload"){var p=r,q=this; 266 | r=function(){q.removeListener("unload",r);p();};}else{k[$uid(this)]=this;}if(this.addEventListener){this.addEventListener(s,r,!!arguments[2]);}else{this.attachEvent("on"+s,r); 267 | }return this;},removeListener:function(q,p){if(this.removeEventListener){this.removeEventListener(q,p,!!arguments[2]);}else{this.detachEvent("on"+q,p); 268 | }return this;},retrieve:function(q,p){var s=e($uid(this)),r=s[q];if(p!=null&&r==null){r=s[q]=p;}return r!=null?r:null;},store:function(q,p){var r=e($uid(this)); 269 | r[q]=p;return this;},eliminate:function(p){var q=e($uid(this));delete q[p];return this;}});if(window.attachEvent&&!window.addEventListener){window.addListener("unload",function(){Object.each(k,j); 270 | if(window.CollectGarbage){CollectGarbage();}});}})();Element.Properties={};Element.Properties.style={set:function(a){this.style.cssText=a;},get:function(){return this.style.cssText; 271 | },erase:function(){this.style.cssText="";}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();}};(function(a){if(a!=null){Element.Properties.maxlength=Element.Properties.maxLength={get:function(){var b=this.getAttribute("maxLength"); 272 | return b==a?null:b;}};}})(document.createElement("input").getAttribute("maxLength"));Element.Properties.html=(function(){var c=Function.attempt(function(){var e=document.createElement("table"); 273 | e.innerHTML="";});var d=document.createElement("div");var a={table:[1,"","
"],select:[1,""],tbody:[2,"","
"],tr:[3,"","
"]}; 274 | a.thead=a.tfoot=a.tbody;var b={set:function(){var f=Array.flatten(arguments).join("");var g=(!c&&a[this.get("tag")]);if(g){var h=d;h.innerHTML=g[1]+f+g[2]; 275 | for(var e=g[0];e--;){h=h.firstChild;}this.empty().adopt(h.childNodes);}else{this.innerHTML=f;}}};b.erase=b.set;return b;})();(function(){var c=document.html; 276 | Element.Properties.styles={set:function(f){this.setStyles(f);}};var e=(c.style.opacity!=null);var d=/alpha\(opacity=([\d.]+)\)/i;var b=function(g,f){if(!g.currentStyle||!g.currentStyle.hasLayout){g.style.zoom=1; 277 | }if(e){g.style.opacity=f;}else{f=(f*100).limit(0,100).round();f=(f==100)?"":"alpha(opacity="+f+")";var h=g.style.filter||g.getComputedStyle("filter")||""; 278 | g.style.filter=d.test(h)?h.replace(d,f):h+f;}};Element.Properties.opacity={set:function(g){var f=this.style.visibility;if(g==0&&f!="hidden"){this.style.visibility="hidden"; 279 | }else{if(g!=0&&f!="visible"){this.style.visibility="visible";}}b(this,g);},get:(e)?function(){var f=this.style.opacity||this.getComputedStyle("opacity"); 280 | return(f=="")?1:f;}:function(){var f,g=(this.style.filter||this.getComputedStyle("filter"));if(g){f=g.match(d);}return(f==null||g==null)?1:(f[1]/100);}}; 281 | var a=(c.style.cssFloat==null)?"styleFloat":"cssFloat";Element.implement({getComputedStyle:function(h){if(this.currentStyle){return this.currentStyle[h.camelCase()]; 282 | }var g=Element.getDocument(this).defaultView,f=g?g.getComputedStyle(this,null):null;return(f)?f.getPropertyValue((h==a)?"float":h.hyphenate()):null;},setOpacity:function(f){b(this,f); 283 | return this;},getOpacity:function(){return this.get("opacity");},setStyle:function(g,f){switch(g){case"opacity":return this.set("opacity",parseFloat(f)); 284 | case"float":g=a;}g=g.camelCase();if(typeOf(f)!="string"){var h=(Element.Styles[g]||"@").split(" ");f=Array.from(f).map(function(k,j){if(!h[j]){return""; 285 | }return(typeOf(k)=="number")?h[j].replace("@",Math.round(k)):k;}).join(" ");}else{if(f==String(Number(f))){f=Math.round(f);}}this.style[g]=f;return this; 286 | },getStyle:function(l){switch(l){case"opacity":return this.get("opacity");case"float":l=a;}l=l.camelCase();var f=this.style[l];if(!f||l=="zIndex"){f=[]; 287 | for(var k in Element.ShortStyles){if(l!=k){continue;}for(var j in Element.ShortStyles[k]){f.push(this.getStyle(j));}return f.join(" ");}f=this.getComputedStyle(l); 288 | }if(f){f=String(f);var h=f.match(/rgba?\([\d\s,]+\)/);if(h){f=f.replace(h[0],h[0].rgbToHex());}}if(Browser.opera||(Browser.ie&&isNaN(parseFloat(f)))){if((/^(height|width)$/).test(l)){var g=(l=="width")?["left","right"]:["top","bottom"],i=0; 289 | g.each(function(m){i+=this.getStyle("border-"+m+"-width").toInt()+this.getStyle("padding-"+m).toInt();},this);return this["offset"+l.capitalize()]-i+"px"; 290 | }if(Browser.opera&&String(f).indexOf("px")!=-1){return f;}if((/^border(.+)Width|margin|padding/).test(l)){return"0px";}}return f;},setStyles:function(g){for(var f in g){this.setStyle(f,g[f]); 291 | }return this;},getStyles:function(){var f={};Array.flatten(arguments).each(function(g){f[g]=this.getStyle(g);},this);return f;}});Element.Styles={left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"}; 292 | Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(l){var k=Element.ShortStyles; 293 | var g=Element.Styles;["margin","padding"].each(function(m){var n=m+l;k[m][n]=g[n]="@px";});var j="border"+l;k.border[j]=g[j]="@px @ rgb(@, @, @)";var i=j+"Width",f=j+"Style",h=j+"Color"; 294 | k[j]={};k.borderWidth[i]=k[j][i]=g[i]="@px";k.borderStyle[f]=k[j][f]=g[f]="@";k.borderColor[h]=k[j][h]=g[h]="rgb(@, @, @)";});})();(function(){var h=document.createElement("div"),e=document.createElement("div"); 295 | h.style.height="0";h.appendChild(e);var d=(e.offsetParent===h);h=e=null;var l=function(m){return k(m,"position")!="static"||a(m);};var i=function(m){return l(m)||(/^(?:table|td|th)$/i).test(m.tagName); 296 | };Element.implement({scrollTo:function(m,n){if(a(this)){this.getWindow().scrollTo(m,n);}else{this.scrollLeft=m;this.scrollTop=n;}return this;},getSize:function(){if(a(this)){return this.getWindow().getSize(); 297 | }return{x:this.offsetWidth,y:this.offsetHeight};},getScrollSize:function(){if(a(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight}; 298 | },getScroll:function(){if(a(this)){return this.getWindow().getScroll();}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var n=this.parentNode,m={x:0,y:0}; 299 | while(n&&!a(n)){m.x+=n.scrollLeft;m.y+=n.scrollTop;n=n.parentNode;}return m;},getOffsetParent:d?function(){var m=this;if(a(m)||k(m,"position")=="fixed"){return null; 300 | }var n=(k(m,"position")=="static")?i:l;while((m=m.parentNode)){if(n(m)){return m;}}return null;}:function(){var m=this;if(a(m)||k(m,"position")=="fixed"){return null; 301 | }try{return m.offsetParent;}catch(n){}return null;},getOffsets:function(){if(this.getBoundingClientRect&&!Browser.Platform.ios){var r=this.getBoundingClientRect(),o=document.id(this.getDocument().documentElement),q=o.getScroll(),t=this.getScrolls(),s=(k(this,"position")=="fixed"); 302 | return{x:r.left.toInt()+t.x+((s)?0:q.x)-o.clientLeft,y:r.top.toInt()+t.y+((s)?0:q.y)-o.clientTop};}var n=this,m={x:0,y:0};if(a(this)){return m;}while(n&&!a(n)){m.x+=n.offsetLeft; 303 | m.y+=n.offsetTop;if(Browser.firefox){if(!c(n)){m.x+=b(n);m.y+=g(n);}var p=n.parentNode;if(p&&k(p,"overflow")!="visible"){m.x+=b(p);m.y+=g(p);}}else{if(n!=this&&Browser.safari){m.x+=b(n); 304 | m.y+=g(n);}}n=n.offsetParent;}if(Browser.firefox&&!c(this)){m.x-=b(this);m.y-=g(this);}return m;},getPosition:function(p){if(a(this)){return{x:0,y:0};}var q=this.getOffsets(),n=this.getScrolls(); 305 | var m={x:q.x-n.x,y:q.y-n.y};if(p&&(p=document.id(p))){var o=p.getPosition();return{x:m.x-o.x-b(p),y:m.y-o.y-g(p)};}return m;},getCoordinates:function(o){if(a(this)){return this.getWindow().getCoordinates(); 306 | }var m=this.getPosition(o),n=this.getSize();var p={left:m.x,top:m.y,width:n.x,height:n.y};p.right=p.left+p.width;p.bottom=p.top+p.height;return p;},computePosition:function(m){return{left:m.x-j(this,"margin-left"),top:m.y-j(this,"margin-top")}; 307 | },setPosition:function(m){return this.setStyles(this.computePosition(m));}});[Document,Window].invoke("implement",{getSize:function(){var m=f(this);return{x:m.clientWidth,y:m.clientHeight}; 308 | },getScroll:function(){var n=this.getWindow(),m=f(this);return{x:n.pageXOffset||m.scrollLeft,y:n.pageYOffset||m.scrollTop};},getScrollSize:function(){var o=f(this),n=this.getSize(),m=this.getDocument().body; 309 | return{x:Math.max(o.scrollWidth,m.scrollWidth,n.x),y:Math.max(o.scrollHeight,m.scrollHeight,n.y)};},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var m=this.getSize(); 310 | return{top:0,left:0,bottom:m.y,right:m.x,height:m.y,width:m.x};}});var k=Element.getComputedStyle;function j(m,n){return k(m,n).toInt()||0;}function c(m){return k(m,"-moz-box-sizing")=="border-box"; 311 | }function g(m){return j(m,"border-top-width");}function b(m){return j(m,"border-left-width");}function a(m){return(/^(?:body|html)$/i).test(m.tagName); 312 | }function f(m){var n=m.getDocument();return(!n.compatMode||n.compatMode=="CSS1Compat")?n.html:n.body;}})();Element.alias({position:"setPosition"});[Window,Document,Element].invoke("implement",{getHeight:function(){return this.getSize().y; 313 | },getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;},getScrollLeft:function(){return this.getScroll().x; 314 | },getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;},getTop:function(){return this.getPosition().y; 315 | },getLeft:function(){return this.getPosition().x;}});(function(){var a=Object.prototype.hasOwnProperty;Object.extend({subset:function(d,g){var f={};for(var e=0,b=g.length; 316 | e0&&d<13){p="f"+d;}}if(!p){p=String.fromCharCode(b).toLowerCase(); 325 | }}else{if((/click|mouse|menu/i).test(n)){o=(!o.compatMode||o.compatMode=="CSS1Compat")?o.html:o.body;m={x:(a.pageX!=null)?a.pageX:a.clientX+o.scrollLeft,y:(a.pageY!=null)?a.pageY:a.clientY+o.scrollTop}; 326 | c={x:(a.pageX!=null)?a.pageX-i.pageXOffset:a.clientX,y:(a.pageY!=null)?a.pageY-i.pageYOffset:a.clientY};if((/DOMMouseScroll|mousewheel/).test(n)){l=(a.wheelDelta)?a.wheelDelta/120:-(a.detail||0)/3; 327 | }h=(a.which==3)||(a.button==2);if((/over|out/).test(n)){q=a.relatedTarget||a[(n=="mouseover"?"from":"to")+"Element"];var j=function(){while(q&&q.nodeType==3){q=q.parentNode; 328 | }return true;};var g=(Browser.firefox2)?j.attempt():j();q=(g)?q:null;}}else{if((/gesture|touch/i).test(n)){this.rotation=a.rotation;this.scale=a.scale; 329 | this.targetTouches=a.targetTouches;this.changedTouches=a.changedTouches;var f=this.touches=a.touches;if(f&&f[0]){var e=f[0];m={x:e.pageX,y:e.pageY};c={x:e.clientX,y:e.clientY}; 330 | }}}}return Object.append(this,{event:a,type:n,page:m,client:c,rightClick:h,wheel:l,relatedTarget:document.id(q),target:document.id(k),code:b,key:p,shift:a.shiftKey,control:a.ctrlKey,alt:a.altKey,meta:a.metaKey}); 331 | });Event.Keys={enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46};Event.implement({stop:function(){return this.stopPropagation().preventDefault(); 332 | },stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault(); 333 | }else{this.event.returnValue=false;}return this;}});(function(){Element.Properties.events={set:function(b){this.addEvents(b);}};[Element,Window,Document].invoke("implement",{addEvent:function(f,h){var i=this.retrieve("events",{}); 334 | if(!i[f]){i[f]={keys:[],values:[]};}if(i[f].keys.contains(h)){return this;}i[f].keys.push(h);var g=f,b=Element.Events[f],d=h,j=this;if(b){if(b.onAdd){b.onAdd.call(this,h); 335 | }if(b.condition){d=function(k){if(b.condition.call(this,k)){return h.call(this,k);}return true;};}g=b.base||g;}var e=function(){return h.call(j);};var c=Element.NativeEvents[g]; 336 | if(c){if(c==2){e=function(k){k=new Event(k,j.getWindow());if(d.call(j,k)===false){k.stop();}};}this.addListener(g,e,arguments[2]);}i[f].values.push(e); 337 | return this;},removeEvent:function(e,d){var c=this.retrieve("events");if(!c||!c[e]){return this;}var h=c[e];var b=h.keys.indexOf(d);if(b==-1){return this; 338 | }var g=h.values[b];delete h.keys[b];delete h.values[b];var f=Element.Events[e];if(f){if(f.onRemove){f.onRemove.call(this,d);}e=f.base||e;}return(Element.NativeEvents[e])?this.removeListener(e,g,arguments[2]):this; 339 | },addEvents:function(b){for(var c in b){this.addEvent(c,b[c]);}return this;},removeEvents:function(b){var d;if(typeOf(b)=="object"){for(d in b){this.removeEvent(d,b[d]); 340 | }return this;}var c=this.retrieve("events");if(!c){return this;}if(!b){for(d in c){this.removeEvents(d);}this.eliminate("events");}else{if(c[b]){c[b].keys.each(function(e){this.removeEvent(b,e); 341 | },this);delete c[b];}}return this;},fireEvent:function(e,c,b){var d=this.retrieve("events");if(!d||!d[e]){return this;}c=Array.from(c);d[e].keys.each(function(f){if(b){f.delay(b,this,c); 342 | }else{f.apply(this,c);}},this);return this;},cloneEvents:function(e,d){e=document.id(e);var c=e.retrieve("events");if(!c){return this;}if(!d){for(var b in c){this.cloneEvents(e,b); 343 | }}else{if(c[d]){c[d].keys.each(function(f){this.addEvent(d,f);},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,orientationchange:2,touchstart:2,touchmove:2,touchend:2,touchcancel:2,gesturestart:2,gesturechange:2,gestureend:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:2,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1}; 344 | var a=function(b){var c=b.relatedTarget;if(c==null){return true;}if(!c){return false;}return(c!=this&&c.prefix!="xul"&&typeOf(this)!="document"&&!this.contains(c)); 345 | };Element.Events={mouseenter:{base:"mouseover",condition:a},mouseleave:{base:"mouseout",condition:a},mousewheel:{base:(Browser.firefox)?"DOMMouseScroll":"mousewheel"}}; 346 | })();(function(i,k){var l,f,e=[],c,b,d=k.createElement("div");var g=function(){clearTimeout(b);if(l){return;}Browser.loaded=l=true;k.removeListener("DOMContentLoaded",g).removeListener("readystatechange",a); 347 | k.fireEvent("domready");i.fireEvent("domready");};var a=function(){for(var m=e.length;m--;){if(e[m]()){g();return true;}}return false;};var j=function(){clearTimeout(b); 348 | if(!a()){b=setTimeout(j,10);}};k.addListener("DOMContentLoaded",g);var h=function(){try{d.doScroll();return true;}catch(m){}return false;};if(d.doScroll&&!h()){e.push(h); 349 | c=true;}if(k.readyState){e.push(function(){var m=k.readyState;return(m=="loaded"||m=="complete");});}if("onreadystatechange" in k){k.addListener("readystatechange",a); 350 | }else{c=true;}if(c){j();}Element.Events.domready={onAdd:function(m){if(l){m.call(this);}}};Element.Events.load={base:"load",onAdd:function(m){if(f&&this==i){m.call(this); 351 | }},condition:function(){if(this==i){g();delete Element.Events.load;}return true;}};i.addEvent("load",function(){f=true;});})(window,document); 352 | -------------------------------------------------------------------------------- /mootools/mootools-more-1.3.2.1.js: -------------------------------------------------------------------------------- 1 | // MooTools: the javascript framework. 2 | // Load this file's selection again by visiting: http://mootools.net/more/5b3121b84b8151d70a6f190d1e693180 3 | // Or build this file again with packager using: packager build More/More More/Drag 4 | /* 5 | --- 6 | copyrights: 7 | - [MooTools](http://mootools.net) 8 | 9 | licenses: 10 | - [MIT License](http://mootools.net/license.txt) 11 | ... 12 | */ 13 | MooTools.More={version:"1.3.2.1",build:"e586bcd2496e9b22acfde32e12f84d49ce09e59d"};var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:"left",y:"top"}},initialize:function(){var b=Array.link(arguments,{options:Type.isObject,element:function(c){return c!=null; 14 | }});this.element=document.id(b.element);this.document=this.element.getDocument();this.setOptions(b.options||{});var a=typeOf(this.options.handle);this.handles=((a=="array"||a=="collection")?$$(this.options.handle):document.id(this.options.handle))||this.element; 15 | this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.ie)?"selectstart":"mousedown";if(Browser.ie&&!Drag.ondragstartFixed){document.ondragstart=Function.from(false); 16 | Drag.ondragstartFixed=true;}this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:Function.from(false)}; 17 | this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start); 18 | return this;},start:function(a){var j=this.options;if(a.rightClick){return;}if(j.preventDefault){a.preventDefault();}if(j.stopPropagation){a.stopPropagation(); 19 | }this.mouse.start=a.page;this.fireEvent("beforeStart",this.element);var c=j.limit;this.limit={x:[],y:[]};var e,g;for(e in j.modifiers){if(!j.modifiers[e]){continue; 20 | }var b=this.element.getStyle(j.modifiers[e]);if(b&&!b.match(/px$/)){if(!g){g=this.element.getCoordinates(this.element.getOffsetParent());}b=g[j.modifiers[e]]; 21 | }if(j.style){this.value.now[e]=(b||0).toInt();}else{this.value.now[e]=this.element[j.modifiers[e]];}if(j.invert){this.value.now[e]*=-1;}this.mouse.pos[e]=a.page[e]-this.value.now[e]; 22 | if(c&&c[e]){var d=2;while(d--){var f=c[e][d];if(f||f===0){this.limit[e][d]=(typeof f=="function")?f():f;}}}}if(typeOf(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid}; 23 | }var h={mousemove:this.bound.check,mouseup:this.bound.cancel};h[this.selection]=this.bound.eventStop;this.document.addEvents(h);},check:function(a){if(this.options.preventDefault){a.preventDefault(); 24 | }var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2)));if(b>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop}); 25 | this.fireEvent("start",[this.element,a]).fireEvent("snap",this.element);}},drag:function(b){var a=this.options;if(a.preventDefault){b.preventDefault(); 26 | }this.mouse.now=b.page;for(var c in a.modifiers){if(!a.modifiers[c]){continue;}this.value.now[c]=this.mouse.now[c]-this.mouse.pos[c];if(a.invert){this.value.now[c]*=-1; 27 | }if(a.limit&&this.limit[c]){if((this.limit[c][1]||this.limit[c][1]===0)&&(this.value.now[c]>this.limit[c][1])){this.value.now[c]=this.limit[c][1];}else{if((this.limit[c][0]||this.limit[c][0]===0)&&(this.value.now[c]1e-9};Voronoi.prototype.greaterThanOrEqualWithEpsilon=function(d,c){return c-d<1e-9 13 | };Voronoi.prototype.lessThanWithEpsilon=function(d,c){return c-d>1e-9};Voronoi.prototype.lessThanOrEqualWithEpsilon=function(d,c){return d-c<1e-9 14 | };Voronoi.prototype.RBTree=function(){this.root=null};Voronoi.prototype.RBTree.prototype.rbInsertSuccessor=function(e,a){var d; 15 | if(e){a.rbPrevious=e;a.rbNext=e.rbNext;if(e.rbNext){e.rbNext.rbPrevious=a}e.rbNext=a;if(e.rbRight){e=e.rbRight;while(e.rbLeft){e=e.rbLeft 16 | }e.rbLeft=a}else{e.rbRight=a}d=e}else{if(this.root){e=this.getFirst(this.root);a.rbPrevious=null;a.rbNext=e;e.rbPrevious=a; 17 | e.rbLeft=a;d=e}else{a.rbPrevious=a.rbNext=null;this.root=a;d=null}}a.rbLeft=a.rbRight=null;a.rbParent=d;a.rbRed=true;var c,b; 18 | e=a;while(d&&d.rbRed){c=d.rbParent;if(d===c.rbLeft){b=c.rbRight;if(b&&b.rbRed){d.rbRed=b.rbRed=false;c.rbRed=true;e=c}else{if(e===d.rbRight){this.rbRotateLeft(d); 19 | e=d;d=e.rbParent}d.rbRed=false;c.rbRed=true;this.rbRotateRight(c)}}else{b=c.rbLeft;if(b&&b.rbRed){d.rbRed=b.rbRed=false;c.rbRed=true; 20 | e=c}else{if(e===d.rbLeft){this.rbRotateRight(d);e=d;d=e.rbParent}d.rbRed=false;c.rbRed=true;this.rbRotateLeft(c)}}d=e.rbParent 21 | }this.root.rbRed=false};Voronoi.prototype.RBTree.prototype.rbRemoveNode=function(f){if(f.rbNext){f.rbNext.rbPrevious=f.rbPrevious 22 | }if(f.rbPrevious){f.rbPrevious.rbNext=f.rbNext}f.rbNext=f.rbPrevious=null;var e=f.rbParent,g=f.rbLeft,b=f.rbRight,d;if(!g){d=b 23 | }else{if(!b){d=g}else{d=this.getFirst(b)}}if(e){if(e.rbLeft===f){e.rbLeft=d}else{e.rbRight=d}}else{this.root=d}var a;if(g&&b){a=d.rbRed; 24 | d.rbRed=f.rbRed;d.rbLeft=g;g.rbParent=d;if(d!==b){e=d.rbParent;d.rbParent=f.rbParent;f=d.rbRight;e.rbLeft=f;d.rbRight=b;b.rbParent=d 25 | }else{d.rbParent=e;e=d;f=d.rbRight}}else{a=f.rbRed;f=d}if(f){f.rbParent=e}if(a){return}if(f&&f.rbRed){f.rbRed=false;return 26 | }var c;do{if(f===this.root){break}if(f===e.rbLeft){c=e.rbRight;if(c.rbRed){c.rbRed=false;e.rbRed=true;this.rbRotateLeft(e); 27 | c=e.rbRight}if((c.rbLeft&&c.rbLeft.rbRed)||(c.rbRight&&c.rbRight.rbRed)){if(!c.rbRight||!c.rbRight.rbRed){c.rbLeft.rbRed=false; 28 | c.rbRed=true;this.rbRotateRight(c);c=e.rbRight}c.rbRed=e.rbRed;e.rbRed=c.rbRight.rbRed=false;this.rbRotateLeft(e);f=this.root; 29 | break}}else{c=e.rbLeft;if(c.rbRed){c.rbRed=false;e.rbRed=true;this.rbRotateRight(e);c=e.rbLeft}if((c.rbLeft&&c.rbLeft.rbRed)||(c.rbRight&&c.rbRight.rbRed)){if(!c.rbLeft||!c.rbLeft.rbRed){c.rbRight.rbRed=false; 30 | c.rbRed=true;this.rbRotateLeft(c);c=e.rbLeft}c.rbRed=e.rbRed;e.rbRed=c.rbLeft.rbRed=false;this.rbRotateRight(e);f=this.root; 31 | break}}c.rbRed=true;f=e;e=e.rbParent}while(!f.rbRed);if(f){f.rbRed=false}};Voronoi.prototype.RBTree.prototype.rbRotateLeft=function(b){var d=b,c=b.rbRight,a=d.rbParent; 32 | if(a){if(a.rbLeft===d){a.rbLeft=c}else{a.rbRight=c}}else{this.root=c}c.rbParent=a;d.rbParent=c;d.rbRight=c.rbLeft;if(d.rbRight){d.rbRight.rbParent=d 33 | }c.rbLeft=d};Voronoi.prototype.RBTree.prototype.rbRotateRight=function(b){var d=b,c=b.rbLeft,a=d.rbParent;if(a){if(a.rbLeft===d){a.rbLeft=c 34 | }else{a.rbRight=c}}else{this.root=c}c.rbParent=a;d.rbParent=c;d.rbLeft=c.rbRight;if(d.rbLeft){d.rbLeft.rbParent=d}c.rbRight=d 35 | };Voronoi.prototype.RBTree.prototype.getFirst=function(a){while(a.rbLeft){a=a.rbLeft}return a};Voronoi.prototype.RBTree.prototype.getLast=function(a){while(a.rbRight){a=a.rbRight 36 | }return a};Voronoi.prototype.Diagram=function(a){this.site=a};Voronoi.prototype.Cell=function(a){this.site=a;this.halfedges=[]; 37 | this.closeMe=false};Voronoi.prototype.Cell.prototype.init=function(a){this.site=a;this.halfedges=[];this.closeMe=false;return this 38 | };Voronoi.prototype.createCell=function(b){var a=this.cellJunkyard.pop();if(a){return a.init(b)}return new this.Cell(b)}; 39 | Voronoi.prototype.Cell.prototype.prepareHalfedges=function(){var a=this.halfedges,b=a.length,c;while(b--){c=a[b].edge;if(!c.vb||!c.va){a.splice(b,1) 40 | }}a.sort(function(e,d){return d.angle-e.angle});return a.length};Voronoi.prototype.Cell.prototype.getNeighborIds=function(){var a=[],b=this.halfedges.length,c; 41 | while(b--){c=this.halfedges[b].edge;if(c.lSite!==null&&c.lSite.voronoiId!=this.site.voronoiId){a.push(c.lSite.voronoiId)}else{if(c.rSite!==null&&c.rSite.voronoiId!=this.site.voronoiId){a.push(c.rSite.voronoiId) 42 | }}}return a};Voronoi.prototype.Cell.prototype.getBbox=function(){var i=this.halfedges,d=i.length,a=Infinity,g=Infinity,c=-Infinity,b=-Infinity,h,f,e; 43 | while(d--){h=i[d].getStartpoint();f=h.x;e=h.y;if(fc){c=f}if(e>b){b=e}}return{x:a,y:g,width:c-a,height:b-g} 44 | };Voronoi.prototype.Cell.prototype.pointIntersection=function(a,h){var b=this.halfedges,c=b.length,f,g,e,d;while(c--){f=b[c]; 45 | g=f.getStartpoint();e=f.getEndpoint();d=(h-g.y)*(e.x-g.x)-(a-g.x)*(e.y-g.y);if(!d){return 0}if(d>0){return -1}}return 1}; 46 | Voronoi.prototype.Vertex=function(a,b){this.x=a;this.y=b};Voronoi.prototype.Edge=function(b,a){this.lSite=b;this.rSite=a; 47 | this.va=this.vb=null};Voronoi.prototype.Halfedge=function(d,e,a){this.site=e;this.edge=d;if(a){this.angle=Math.atan2(a.y-e.y,a.x-e.x) 48 | }else{var c=d.va,b=d.vb;this.angle=d.lSite===e?Math.atan2(b.x-c.x,c.y-b.y):Math.atan2(c.x-b.x,b.y-c.y)}};Voronoi.prototype.createHalfedge=function(b,c,a){return new this.Halfedge(b,c,a) 49 | };Voronoi.prototype.Halfedge.prototype.getStartpoint=function(){return this.edge.lSite===this.site?this.edge.va:this.edge.vb 50 | };Voronoi.prototype.Halfedge.prototype.getEndpoint=function(){return this.edge.lSite===this.site?this.edge.vb:this.edge.va 51 | };Voronoi.prototype.createVertex=function(a,c){var b=this.vertexJunkyard.pop();if(!b){b=new this.Vertex(a,c)}else{b.x=a;b.y=c 52 | }this.vertices.push(b);return b};Voronoi.prototype.createEdge=function(e,a,d,b){var c=this.edgeJunkyard.pop();if(!c){c=new this.Edge(e,a) 53 | }else{c.lSite=e;c.rSite=a;c.va=c.vb=null}this.edges.push(c);if(d){this.setEdgeStartpoint(c,e,a,d)}if(b){this.setEdgeEndpoint(c,e,a,b) 54 | }this.cells[e.voronoiId].halfedges.push(this.createHalfedge(c,e,a));this.cells[a.voronoiId].halfedges.push(this.createHalfedge(c,a,e)); 55 | return c};Voronoi.prototype.createBorderEdge=function(d,c,a){var b=this.edgeJunkyard.pop();if(!b){b=new this.Edge(d,null) 56 | }else{b.lSite=d;b.rSite=null}b.va=c;b.vb=a;this.edges.push(b);return b};Voronoi.prototype.setEdgeStartpoint=function(b,d,a,c){if(!b.va&&!b.vb){b.va=c; 57 | b.lSite=d;b.rSite=a}else{if(b.lSite===a){b.vb=c}else{b.va=c}}};Voronoi.prototype.setEdgeEndpoint=function(b,d,a,c){this.setEdgeStartpoint(b,a,d,c) 58 | };Voronoi.prototype.Beachsection=function(){};Voronoi.prototype.createBeachsection=function(a){var b=this.beachsectionJunkyard.pop(); 59 | if(!b){b=new this.Beachsection()}b.site=a;return b};Voronoi.prototype.leftBreakPoint=function(e,f){var a=e.site,m=a.x,l=a.y,k=l-f; 60 | if(!k){return m}var n=e.rbPrevious;if(!n){return -Infinity}a=n.site;var h=a.x,g=a.y,d=g-f;if(!d){return h}var c=h-m,j=1/k-1/d,i=c/d; 61 | if(j){return(-i+this.sqrt(i*i-2*j*(c*c/(-2*d)-g+d/2+l-k/2)))/j+m}return(m+h)/2};Voronoi.prototype.rightBreakPoint=function(b,c){var d=b.rbNext; 62 | if(d){return this.leftBreakPoint(d,c)}var a=b.site;return a.y===c?a.x:Infinity};Voronoi.prototype.detachBeachsection=function(a){this.detachCircleEvent(a); 63 | this.beachline.rbRemoveNode(a);this.beachsectionJunkyard.push(a)};Voronoi.prototype.removeBeachsection=function(b){var a=b.circleEvent,j=a.x,h=a.ycenter,e=this.createVertex(j,h),f=b.rbPrevious,d=b.rbNext,l=[b],g=Math.abs; 64 | this.detachBeachsection(b);var m=f;while(m.circleEvent&&g(j-m.circleEvent.x)<1e-9&&g(h-m.circleEvent.ycenter)<1e-9){f=m.rbPrevious; 65 | l.unshift(m);this.detachBeachsection(m);m=f}l.unshift(m);this.detachCircleEvent(m);var c=d;while(c.circleEvent&&g(j-c.circleEvent.x)<1e-9&&g(h-c.circleEvent.ycenter)<1e-9){d=c.rbNext; 66 | l.push(c);this.detachBeachsection(c);c=d}l.push(c);this.detachCircleEvent(c);var k=l.length,i;for(i=1;i1e-9){o=o.rbLeft}else{q=j-this.rightBreakPoint(o,n);if(q>1e-9){if(!o.rbRight){p=o; 70 | break}o=o.rbRight}else{if(v>-1e-9){p=o.rbPrevious;m=o}else{if(q>-1e-9){p=o;m=o.rbNext}else{p=m=o}}break}}}var e=this.createBeachsection(l); 71 | this.beachline.rbInsertSuccessor(p,e);if(!p&&!m){return}if(p===m){this.detachCircleEvent(p);m=this.createBeachsection(p.site); 72 | this.beachline.rbInsertSuccessor(e,m);e.edge=m.edge=this.createEdge(p.site,e.site);this.attachCircleEvent(p);this.attachCircleEvent(m); 73 | return}if(p&&!m){e.edge=this.createEdge(p.site,e.site);return}if(p!==m){this.detachCircleEvent(p);this.detachCircleEvent(m); 74 | var h=p.site,k=h.x,i=h.y,t=l.x-k,r=l.y-i,a=m.site,c=a.x-k,b=a.y-i,u=2*(t*b-r*c),g=t*t+r*r,f=c*c+b*b,s=this.createVertex((b*g-r*f)/u+k,(t*f-c*g)/u+i); 75 | this.setEdgeStartpoint(m.edge,h,a,s);e.edge=this.createEdge(h,l,undefined,s);m.edge=this.createEdge(l,a,undefined,s);this.attachCircleEvent(p); 76 | this.attachCircleEvent(m);return}};Voronoi.prototype.CircleEvent=function(){this.arc=null;this.rbLeft=null;this.rbNext=null; 77 | this.rbParent=null;this.rbPrevious=null;this.rbRed=false;this.rbRight=null;this.site=null;this.x=this.y=this.ycenter=0};Voronoi.prototype.attachCircleEvent=function(i){var r=i.rbPrevious,o=i.rbNext; 78 | if(!r||!o){return}var k=r.site,u=i.site,c=o.site;if(k===c){return}var t=u.x,s=u.y,n=k.x-t,l=k.y-s,f=c.x-t,e=c.y-s;var v=2*(n*e-l*f); 79 | if(v>=-2e-12){return}var h=n*n+l*l,g=f*f+e*e,m=(e*h-l*g)/v,j=(n*g-f*h)/v,b=j+s;var q=this.circleEventJunkyard.pop();if(!q){q=new this.CircleEvent() 80 | }q.arc=i;q.site=u;q.x=m+t;q.y=b+this.sqrt(m*m+j*j);q.ycenter=b;i.circleEvent=q;var a=null,p=this.circleEvents.root;while(p){if(q.y=n){return false 86 | }if(i>k){if(!c||c.y=d){return false}}b=this.createVertex(g,d)}else{if(!c||c.y>d){c=this.createVertex(g,d) 87 | }else{if(c.y1){if(i>k){if(!c||c.y=d){return false}}b=this.createVertex((d-q)/m,d)}else{if(!c||c.y>d){c=this.createVertex((d-q)/m,d)}else{if(c.y=n){return false}}b=this.createVertex(n,m*n+q) 90 | }else{if(!c||c.x>n){c=this.createVertex(n,m*n+q)}else{if(c.x0){if(a>e){return false}if(a>f){f=a 93 | }}}c=i.xr-b;if(k===0&&c<0){return false}a=c/k;if(k<0){if(a>e){return false}if(a>f){f=a}}else{if(k>0){if(a0){if(a>e){return false 95 | }if(a>f){f=a}}}c=i.yb-l;if(j===0&&c<0){return false}a=c/j;if(j<0){if(a>e){return false}if(a>f){f=a}}else{if(j>0){if(a0){d.va=this.createVertex(b+f*k,l+f*j)}if(e<1){d.vb=this.createVertex(b+e*k,l+e*j)}if(f>0||e<1){this.cells[d.lSite.voronoiId].closeMe=true; 97 | this.cells[d.rSite.voronoiId].closeMe=true}return true};Voronoi.prototype.clipEdges=function(e){var a=this.edges,d=a.length,c,b=Math.abs; 98 | while(d--){c=a[d];if(!this.connectEdge(c,e)||!this.clipEdge(c,e)||(b(c.va.x-c.vb.x)<1e-9&&b(c.va.y-c.vb.y)<1e-9)){c.va=c.vb=null; 99 | a.splice(d,1)}}};Voronoi.prototype.closeCells=function(p){var g=p.xl,d=p.xr,m=p.yt,j=p.yb,q=this.cells,a=q.length,n,e,o,c,b,l,k,i,f,h=Math.abs; 100 | while(a--){n=q[a];if(!n.prepareHalfedges()){continue}if(!n.closeMe){continue}o=n.halfedges;c=o.length;e=0;while(e=1e-9||h(l.y-i.y)>=1e-9){switch(true){case this.equalWithEpsilon(l.x,g)&&this.lessThanWithEpsilon(l.y,j):f=this.equalWithEpsilon(i.x,g); 102 | k=this.createVertex(g,f?i.y:j);b=this.createBorderEdge(n.site,l,k);e++;o.splice(e,0,this.createHalfedge(b,n.site,null));c++; 103 | if(f){break}l=k;case this.equalWithEpsilon(l.y,j)&&this.lessThanWithEpsilon(l.x,d):f=this.equalWithEpsilon(i.y,j);k=this.createVertex(f?i.x:d,j); 104 | b=this.createBorderEdge(n.site,l,k);e++;o.splice(e,0,this.createHalfedge(b,n.site,null));c++;if(f){break}l=k;case this.equalWithEpsilon(l.x,d)&&this.greaterThanWithEpsilon(l.y,m):f=this.equalWithEpsilon(i.x,d); 105 | k=this.createVertex(d,f?i.y:m);b=this.createBorderEdge(n.site,l,k);e++;o.splice(e,0,this.createHalfedge(b,n.site,null));c++; 106 | if(f){break}l=k;case this.equalWithEpsilon(l.y,m)&&this.greaterThanWithEpsilon(l.x,g):f=this.equalWithEpsilon(i.y,m);k=this.createVertex(f?i.x:g,m); 107 | b=this.createBorderEdge(n.site,l,k);e++;o.splice(e,0,this.createHalfedge(b,n.site,null));c++;if(f){break}l=k;f=this.equalWithEpsilon(i.x,g); 108 | k=this.createVertex(g,f?i.y:j);b=this.createBorderEdge(n.site,l,k);e++;o.splice(e,0,this.createHalfedge(b,n.site,null));c++; 109 | if(f){break}l=k;f=this.equalWithEpsilon(i.y,j);k=this.createVertex(f?i.x:d,j);b=this.createBorderEdge(n.site,l,k);e++;o.splice(e,0,this.createHalfedge(b,n.site,null)); 110 | c++;if(f){break}l=k;f=this.equalWithEpsilon(i.x,d);k=this.createVertex(d,f?i.y:m);b=this.createBorderEdge(n.site,l,k);e++; 111 | o.splice(e,0,this.createHalfedge(b,n.site,null));c++;if(f){break}default:throw"Voronoi.closeCells() > this makes no sense!" 112 | }}e++}n.closeMe=false}};Voronoi.prototype.quantizeSites=function(c){var b=this.ε,d=c.length,a;while(d--){a=c[d];a.x=Math.floor(a.x/b)*b; 113 | a.y=Math.floor(a.y/b)*b}};Voronoi.prototype.recycle=function(a){if(a){if(a instanceof this.Diagram){this.toRecycle=a}else{throw"Voronoi.recycleDiagram() > Need a Diagram object." 114 | }}};Voronoi.prototype.compute=function(i,j){var d=new Date();this.reset();if(this.toRecycle){this.vertexJunkyard=this.vertexJunkyard.concat(this.toRecycle.vertices); 115 | this.edgeJunkyard=this.edgeJunkyard.concat(this.toRecycle.edges);this.cellJunkyard=this.cellJunkyard.concat(this.toRecycle.cells); 116 | this.toRecycle=null}var h=i.slice(0);h.sort(function(n,m){var o=m.y-n.y;if(o){return o}return m.x-n.x});var b=h.pop(),l=0,f,e,k=this.cells,a; 117 | for(;;){a=this.firstCircleEvent;if(b&&(!a||b.y 2 | 3 | 4 | 5 | Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams: Demo 1 6 | 7 | 8 | 9 | 19 | 183 | 184 | 185 | Fork me on GitHub 186 |

Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams
Demo 1: measuring peformance

187 |
188 |

< Back to main page

196 |

Sites generator

197 |
198 | or sites randomly (Warning: performance might suffer the more sites you add.) 199 |
200 |
Result: ? 201 |
202 |

Canvas

203 |
204 | 205 | 206 | 210 |
211 |

Javascript source code for this page

212 |
213 |
214 | <script type="text/javascript" src="rhill-voronoi-core.js"></script>
215 | ...
216 | 
217 | ... 218 |
219 |
220 |
221 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /rhill-voronoi-demo2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams: Demo 2 6 | 7 | 8 | 9 | 20 | 155 | 156 | 157 | Fork me on GitHub 158 |

Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams
Demo 2: A bit of interactivity added

159 |
160 |

< Back to main page

168 |

Sites generator

169 |
170 | or sites randomly (Warning: performance might suffer the more sites you add.) 171 |
172 |
173 |

Canvas

174 |
175 | 176 | 177 | 181 |
182 |

Javascript source code for this page

183 |
184 |
185 | <script type="text/javascript" src="rhill-voronoi-core.js"></script>
186 | ...
187 | 
188 | ... 189 |
190 |
191 |
192 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /rhill-voronoi-demo3.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 33 | 34 | Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams: Demo 3 35 | 36 | 37 | 38 | 41 | 42 | = 6 && $valuesPerTiles <= 8 ) { 49 | for ( $iTile = 0; $iTile < 3; $iTile++ ) { 50 | $index = $iTile * $valuesPerTiles; 51 | $xstep = min(max(hexdec($match[$index++]),0),50); 52 | $ystep = min(max(hexdec($match[$index++]),0),50); 53 | $xoffset = min(max(hexdec($match[$index++]) / 1000 - 0.5,-0.5),0.5); 54 | $yoffset = min(max(hexdec($match[$index++]) / 1000 - 0.5,-0.5),0.5); 55 | $angle = $valuesPerTiles != 7 ? min(max(hexdec($match[$index++])/1000,0),1) : 0; 56 | $tile = "repeatx:{$xstep}, repeaty:{$ystep}, offsetx:{$xoffset}, offsety:{$yoffset}, rotate:{$angle}"; 57 | if ( preg_match('/^[0-9a-fA-F]{6}$/', $match[$index]) ) { 58 | $tile .= ", color:'#{$match[$index]}'"; 59 | } 60 | $tiles[] = "{{$tile}}"; 61 | } 62 | $preset = '[' . implode(',', $tiles) . ']'; 63 | } 64 | } 65 | } 66 | ?> 67 | 571 | 572 | 573 | Fork me on GitHub 574 |

Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams
Demo 3: Fancy tiling

575 |
576 |

< Back to main page

584 |
585 |

Canvas

586 | 587 | 588 | 592 |
593 |   594 |
595 |

1st-degree generators

596 | (This page works best on latest Opera browser: I measured fastest execution + it natively supports HTML5 color picker) 597 |
598 |
599 | Color: ? 600 |
601 |
602 | h 603 | v 604 |
605 |
606 |
Steps
607 |
608 | 609 |
610 |
611 |
Offset
612 |
613 | 614 |
615 |
616 |
Rot
617 |
618 | 619 |
620 |
621 |
622 |
623 | Color: 624 |
625 |
626 | h 627 | v 628 |
629 |
630 |
Steps
631 |
632 | 633 |
634 |
635 |
Offset
636 |
637 | 638 |
639 |
640 |
Rot
641 |
642 | 643 |
644 |
645 |
646 |
647 | Color: 648 |
649 |
650 | h 651 | v 652 |
653 |
654 |
Steps
655 |
656 | 657 |
658 |
659 |
Offset
660 |
661 | 662 |
663 |
664 |
Rot
665 |
666 | 667 |
668 |
669 |
670 | Show grout
671 | Show Voronoi sites 672 |
673 |
674 | Presets:
675 | 688 |
689 |
690 |
691 |
692 |

Permalink for the above Voronoi diagram

693 |

694 |
695 | 702 |
703 |

Export as SVG

704 |

Coming soon (I guess...)

705 |
706 |
707 |

Further reading

708 |

Voronoi diagrams and ornamental design (PDF file) by Craig S. Kaplan.
Mathematical imagery by Jos Leys.

709 |
710 | 711 | 712 | -------------------------------------------------------------------------------- /rhill-voronoi-demo4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams: Demo 4 6 | 7 | 8 | 9 | 10 | 20 | 215 | 216 | 217 | Fork me on GitHub 218 |

Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams
Demo 4: Looking up a Voronoi cell using a quadtree

219 |
220 |

< Back to main page

228 |

Sites generator

229 |
230 | or sites randomly (Warning: performance might suffer the more sites you add.) 231 |
232 |
233 |

Canvas / Cell id at

234 |
235 | 236 | 237 | 241 |
242 |

Javascript source code for this page

243 |
244 |
245 | <script type="text/javascript" src="rhill-voronoi-core.js"></script>
246 | <script type="text/javascript" src="QuadTree.js"></script>
247 | ...
248 | 
249 | ... 250 |
251 |
252 |
253 | 264 | 265 | 266 | -------------------------------------------------------------------------------- /rhill-voronoi-demo5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams: Demo 5 6 | 7 | 8 | 9 | 10 | 20 | 205 | 206 | 207 | Fork me on GitHub 208 |

Javascript implementation of Steven Fortune's algorithm to compute Voronoi diagrams
Demo 5: Lloyd's relaxation

209 |
210 |

< Back to main page

218 |

Sites generator

219 |
220 | or sites randomly (Warning: performance might suffer the more sites you add.) 221 |
222 |
223 |

Canvas

224 |
225 | 226 | 227 | 231 |
232 |

Javascript source code for this page

233 |
234 |
235 | <script type="text/javascript" src="rhill-voronoi-core.js"></script>
236 | ...
237 | 
238 | ... 239 |
240 |
241 |
242 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /rhill-voronoi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Javascript implementation of Steven J. Fortune's algorithm to compute Voronoi diagrams 6 | 7 | 8 | 9 | 23 | 24 | 25 | Fork me on GitHub 26 |

Javascript implementation of Steven J. Fortune's algorithm to compute Voronoi diagrams

27 |
28 |

Main page

36 |

Intro

37 |
38 |

See my blog post regarding this page. This page uses an out of date version (and customized to serve as a tutorial of Fortune's algorithm) of the Javascript Voronoi object. However the demo pages listed above use the latest version.

39 |
40 |

Sites generator

41 |
42 | or sites randomly (Warning: performance might suffer the more sites you add.)
43 |

44 |
45 |
46 | 47 |
48 |

Canvas

49 |
50 |
canvas W × H to pixels × pixels, with a margin of pixels.
51 |
52 |
53 |
54 |
55 | 56 | 57 | 61 |
62 |

Event queue

63 |
64 |
65 |
66 | (down arrow works too)
67 |
68 | 69 |
70 |
71 | pixel(s)
72 | every ms
73 |
74 |

Scrutinize...

75 |
76 | 77 | Red beach sections are collapsing (meaning there is a Fortune circle event associated with them), while green beach sections are expanding. When all the Fortune events have been processed, a beachline most likely still exists, which means the start and/or end points of the edges implied by each pair of beach sections are not connected, in which case we must ‘manually’ connect these dangling lines to the bounding box, or discard them if they are outside the viewport. 78 |
79 |
80 |

Portions of this software are based on, or depend on, or are inspired from the work of...

81 |
82 | 90 |
91 |
92 | 107 | 108 | 109 | --------------------------------------------------------------------------------