newbietk commited on
Commit
7e2d2d6
1 Parent(s): cbb89a0

Upload 10 files

Browse files
Stats.js ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @author mrdoob / http://mrdoob.com/
3
+ */
4
+
5
+ var Stats = function () {
6
+
7
+ var startTime = Date.now(), prevTime = startTime;
8
+ var ms = 0, msMin = Infinity, msMax = 0;
9
+ var fps = 0, fpsMin = Infinity, fpsMax = 0;
10
+ var frames = 0, mode = 0;
11
+
12
+ var container = document.createElement( 'div' );
13
+ container.id = 'stats';
14
+ container.addEventListener( 'mousedown', function ( event ) { event.preventDefault(); setMode( ++ mode % 2 ) }, false );
15
+ container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer';
16
+
17
+ var fpsDiv = document.createElement( 'div' );
18
+ fpsDiv.id = 'fps';
19
+ fpsDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#002';
20
+ container.appendChild( fpsDiv );
21
+
22
+ var fpsText = document.createElement( 'div' );
23
+ fpsText.id = 'fpsText';
24
+ fpsText.style.cssText = 'color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
25
+ fpsText.innerHTML = 'FPS';
26
+ fpsDiv.appendChild( fpsText );
27
+
28
+ var fpsGraph = document.createElement( 'div' );
29
+ fpsGraph.id = 'fpsGraph';
30
+ fpsGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0ff';
31
+ fpsDiv.appendChild( fpsGraph );
32
+
33
+ while ( fpsGraph.children.length < 74 ) {
34
+
35
+ var bar = document.createElement( 'span' );
36
+ bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#113';
37
+ fpsGraph.appendChild( bar );
38
+
39
+ }
40
+
41
+ var msDiv = document.createElement( 'div' );
42
+ msDiv.id = 'ms';
43
+ msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;display:none';
44
+ container.appendChild( msDiv );
45
+
46
+ var msText = document.createElement( 'div' );
47
+ msText.id = 'msText';
48
+ msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
49
+ msText.innerHTML = 'MS';
50
+ msDiv.appendChild( msText );
51
+
52
+ var msGraph = document.createElement( 'div' );
53
+ msGraph.id = 'msGraph';
54
+ msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0';
55
+ msDiv.appendChild( msGraph );
56
+
57
+ while ( msGraph.children.length < 74 ) {
58
+
59
+ var bar = document.createElement( 'span' );
60
+ bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131';
61
+ msGraph.appendChild( bar );
62
+
63
+ }
64
+
65
+ var setMode = function ( value ) {
66
+
67
+ mode = value;
68
+
69
+ switch ( mode ) {
70
+
71
+ case 0:
72
+ fpsDiv.style.display = 'block';
73
+ msDiv.style.display = 'none';
74
+ break;
75
+ case 1:
76
+ fpsDiv.style.display = 'none';
77
+ msDiv.style.display = 'block';
78
+ break;
79
+ }
80
+
81
+ }
82
+
83
+ var updateGraph = function ( dom, value ) {
84
+
85
+ var child = dom.appendChild( dom.firstChild );
86
+ child.style.height = value + 'px';
87
+
88
+ }
89
+
90
+ return {
91
+
92
+ REVISION: 11,
93
+
94
+ domElement: container,
95
+
96
+ setMode: setMode,
97
+
98
+ begin: function () {
99
+
100
+ startTime = Date.now();
101
+
102
+ },
103
+
104
+ end: function () {
105
+
106
+ var time = Date.now();
107
+
108
+ ms = time - startTime;
109
+ msMin = Math.min( msMin, ms );
110
+ msMax = Math.max( msMax, ms );
111
+
112
+ msText.textContent = ms + ' MS (' + msMin + '-' + msMax + ')';
113
+ updateGraph( msGraph, Math.min( 30, 30 - ( ms / 200 ) * 30 ) );
114
+
115
+ frames ++;
116
+
117
+ if ( time > prevTime + 1000 ) {
118
+
119
+ fps = Math.round( ( frames * 1000 ) / ( time - prevTime ) );
120
+ fpsMin = Math.min( fpsMin, fps );
121
+ fpsMax = Math.max( fpsMax, fps );
122
+
123
+ fpsText.textContent = fps + ' FPS (' + fpsMin + '-' + fpsMax + ')';
124
+ updateGraph( fpsGraph, Math.min( 30, 30 - ( fps / 100 ) * 30 ) );
125
+
126
+ prevTime = time;
127
+ frames = 0;
128
+
129
+ }
130
+
131
+ return time;
132
+
133
+ },
134
+
135
+ update: function () {
136
+
137
+ startTime = this.end();
138
+
139
+ }
140
+
141
+ }
142
+
143
+ };
TweenMax.min.js ADDED
The diff for this file is too large to render. See raw diff
 
css_globe_PerspectiveTransform.js ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Optimized version of PerspectiveTransform.js
3
+ * by Edan Kwan
4
+ * website: http://www.edankwan.com/
5
+ * twitter: https://twitter.com/#!/edankwan
6
+ * Lab: www.edankwan.com/lab
7
+ *
8
+ * The original PerspectiveTransform.js is created by Israel Pastrana
9
+ * http://www.is-real.net/experiments/css3/wonder-webkit/js/real/display/PerspectiveTransform.js
10
+ *
11
+ * Matrix Libraries from a Java port of JAMA: A Java Matrix Package, http://math.nist.gov/javanumerics/jama/
12
+ * Developed by Dr Peter Coxhead: http://www.cs.bham.ac.uk/~pxc/
13
+ * Available here: http://www.cs.bham.ac.uk/~pxc/js/
14
+ *
15
+ * I simply removed some irrelevant variables and functions and merge everything into a smaller function. I also added some error checking functions and bug fixing things.
16
+ */
17
+ (function (define) {
18
+ define(function(){
19
+
20
+ function PerspectiveTransform(element, width, height, useBackFacing){
21
+
22
+ this.element = element;
23
+ this.style = element.style;
24
+ this.computedStyle = window.getComputedStyle(element);
25
+ this.width = width;
26
+ this.height = height;
27
+ this.useBackFacing = !!useBackFacing;
28
+
29
+ this.topLeft = {x: 0, y: 0};
30
+ this.topRight = {x: width, y: 0};
31
+ this.bottomLeft = {x: 0, y: height};
32
+ this.bottomRight = {x: width, y: height};
33
+ this.calcStyle = '';
34
+ }
35
+
36
+ PerspectiveTransform.useDPRFix = false;
37
+ PerspectiveTransform.dpr = 1;
38
+
39
+ PerspectiveTransform.prototype = (function(){
40
+
41
+ var app = {
42
+ stylePrefix: ''
43
+ };
44
+
45
+ var aM = [[0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0]];
46
+ var bM = [0, 0, 0, 0, 0, 0, 0, 0];
47
+
48
+ function _setTransformStyleName(){
49
+ var testStyle = document.createElement('div').style;
50
+ app.stylePrefix =
51
+ 'webkitTransform' in testStyle ? 'webkit' :
52
+ 'MozTransform' in testStyle ? 'Moz' :
53
+ 'msTransform' in testStyle ? 'ms' :
54
+ '';
55
+ PerspectiveTransform.transformStyleName = app.stylePrefix + (app.stylePrefix.length>0?'Transform':'transform');
56
+ PerspectiveTransform.transformDomStyleName = '-'+app.stylePrefix.toLowerCase()+'-transform';
57
+ PerspectiveTransform.transformOriginStyleName = app.stylePrefix + (app.stylePrefix.length>0?'TransformOrigin':'transformOrigin');
58
+ PerspectiveTransform.transformOriginDomStyleName = '-'+app.stylePrefix.toLowerCase()+'-transform-origin';
59
+ }
60
+
61
+
62
+ // Check the distances between each points and if there is some points with the distance lequal to or less than 1 pixel, then return true. Otherwise return false;
63
+ function _hasDistancesError(){
64
+ var lenX = this.topLeft.x - this.topRight.x;
65
+ var lenY = this.topLeft.y - this.topRight.y;
66
+ if(Math.sqrt(lenX * lenX + lenY * lenY)<=1) return true;
67
+ lenX = this.bottomLeft.x - this.bottomRight.x;
68
+ lenY = this.bottomLeft.y - this.bottomRight.y;
69
+ if(Math.sqrt(lenX * lenX + lenY * lenY)<=1) return true;
70
+ lenX = this.topLeft.x - this.bottomLeft.x;
71
+ lenY = this.topLeft.y - this.bottomLeft.y;
72
+ if(Math.sqrt(lenX * lenX + lenY * lenY)<=1) return true;
73
+ lenX = this.topRight.x - this.bottomRight.x;
74
+ lenY = this.topRight.y - this.bottomRight.y;
75
+ if( Math.sqrt(lenX * lenX + lenY * lenY)<=1) return true;
76
+ lenX = this.topLeft.x - this.bottomRight.x;
77
+ lenY = this.topLeft.y - this.bottomRight.y;
78
+ if( Math.sqrt(lenX * lenX + lenY * lenY)<=1) return true;
79
+ lenX = this.topRight.x - this.bottomLeft.x;
80
+ lenY = this.topRight.y - this.bottomLeft.y;
81
+ if( Math.sqrt(lenX * lenX + lenY * lenY)<=1) return true;
82
+
83
+ return false;
84
+ }
85
+
86
+ // Get the determinant of given 3 points
87
+ function _getDeterminant(p0, p1, p2){
88
+ return p0.x * p1.y + p1.x * p2.y + p2.x * p0.y - p0.y * p1.x - p1.y * p2.x - p2.y * p0.x;
89
+ }
90
+
91
+ // Return true if it is a concave polygon or if it is backfacing when the useBackFacing property is false. Otehrwise return true;
92
+ function _hasPolyonError(){
93
+ var det1 = _getDeterminant(this.topLeft, this.topRight, this.bottomRight);
94
+ var det2 = _getDeterminant(this.bottomRight, this.bottomLeft, this.topLeft);
95
+ if(this.useBackFacing){
96
+ if(det1*det2<=0) return true;
97
+ }else{
98
+ if(det1<=0||det2<=0) return true;
99
+ }
100
+ var det1 = _getDeterminant(this.topRight, this.bottomRight, this.bottomLeft);
101
+ var det2 = _getDeterminant(this.bottomLeft, this.topLeft, this.topRight);
102
+ if(this.useBackFacing){
103
+ if(det1*det2<=0) return true;
104
+ }else{
105
+ if(det1<=0||det2<=0) return true;
106
+ }
107
+ return false;
108
+ }
109
+
110
+ function checkError(){
111
+ if(_hasDistancesError.apply(this)) return 1; // Points are too close to each other.
112
+ if(_hasPolyonError.apply(this)) return 2; // Concave or backfacing if the useBackFacing property is false
113
+ return 0; // no error
114
+ }
115
+
116
+ function calc() {
117
+ var width = this.width;
118
+ var height = this.height;
119
+
120
+ // get the offset from the transfrom origin of the element
121
+ var offsetX = 0;
122
+ var offsetY = 0;
123
+ var offset = this.computedStyle.getPropertyValue(PerspectiveTransform.transformOriginDomStyleName);
124
+ if(offset.indexOf('px')>-1){
125
+ offset = offset.split('px');
126
+ offsetX = -parseFloat(offset[0]);
127
+ offsetY = -parseFloat(offset[1]);
128
+ }else if(offset.indexOf('%')>-1){
129
+ offset = offset.split('%');
130
+ offsetX = -parseFloat(offset[0]) * width / 100;
131
+ offsetY = -parseFloat(offset[1]) * height / 100;
132
+ }
133
+
134
+ // magic here:
135
+ var dst = [this.topLeft, this.topRight, this.bottomLeft, this.bottomRight];
136
+ var arr = [0, 1, 2, 3, 4, 5, 6, 7];
137
+ for(var i = 0; i < 4; i++) {
138
+ aM[i][0] = aM[i+4][3] = i & 1 ? width + offsetX : offsetX;
139
+ aM[i][1] = aM[i+4][4] = (i > 1 ? height + offsetY : offsetY);
140
+ aM[i][6] = (i & 1 ? -offsetX-width : -offsetX) * (dst[i].x + offsetX);
141
+ aM[i][7] = (i > 1 ? -offsetY-height : -offsetY) * (dst[i].x + offsetX);
142
+ aM[i+4][6] = (i & 1 ? -offsetX-width : -offsetX) * (dst[i].y + offsetY);
143
+ aM[i+4][7] = (i > 1 ? -offsetY-height : -offsetY) * (dst[i].y + offsetY);
144
+ bM[i] = (dst[i].x + offsetX);
145
+ bM[i + 4] = (dst[i].y + offsetY);
146
+ aM[i][2] = aM[i+4][5] = 1;
147
+ aM[i][3] = aM[i][4] = aM[i][5] = aM[i+4][0] = aM[i+4][1] = aM[i+4][2] = 0;
148
+ }
149
+ var kmax, sum;
150
+ var row;
151
+ var col = [];
152
+ var i, j, k, tmp;
153
+ for(var j = 0; j < 8; j++) {
154
+ for(var i = 0; i < 8; i++) col[i] = aM[i][j];
155
+ for(i = 0; i < 8; i++) {
156
+ row = aM[i];
157
+ kmax = i<j?i:j;
158
+ sum = 0.0;
159
+ for(var k = 0; k < kmax; k++) sum += row[k] * col[k];
160
+ row[j] = col[i] -= sum;
161
+ }
162
+ var p = j;
163
+ for(i = j + 1; i < 8; i++) {
164
+ if(Math.abs(col[i]) > Math.abs(col[p])) p = i;
165
+ }
166
+ if(p != j) {
167
+ for(k = 0; k < 8; k++) {
168
+ tmp = aM[p][k];
169
+ aM[p][k] = aM[j][k];
170
+ aM[j][k] = tmp;
171
+ }
172
+ tmp = arr[p];
173
+ arr[p] = arr[j];
174
+ arr[j] = tmp;
175
+ }
176
+ if(aM[j][j] != 0.0) for(i = j + 1; i < 8; i++) aM[i][j] /= aM[j][j];
177
+ }
178
+ for(i = 0; i < 8; i++) arr[i] = bM[arr[i]];
179
+ for(k = 0; k < 8; k++) {
180
+ for(i = k + 1; i < 8; i++) arr[i] -= arr[k] * aM[i][k];
181
+ }
182
+ for(k = 7; k > -1; k--) {
183
+ arr[k] /= aM[k][k];
184
+ for(i = 0; i < k; i++) arr[i] -= arr[k] * aM[i][k];
185
+ }
186
+
187
+ return this.calcStyle = 'matrix3d(' + arr[0].toFixed(9) + ',' + arr[3].toFixed(9) + ', 0,' + arr[6].toFixed(9) + ',' + arr[1].toFixed(9) + ',' + arr[4].toFixed(9) + ', 0,' + arr[7].toFixed(9) + ',0, 0, 1, 0,' + arr[2].toFixed(9) + ',' + arr[5].toFixed(9) + ', 0, 1)';
188
+
189
+ }
190
+
191
+ function update(style) {
192
+
193
+ style = style || this.calcStyle;
194
+
195
+ if(PerspectiveTransform.useDPRFix) {
196
+ var dpr = PerspectiveTransform.dpr;
197
+ style = 'scale(' + dpr + ',' + dpr + ')perspective(1000px)' + style + 'translateZ('+ ((1 - dpr) * 1000) + 'px)';
198
+ }
199
+
200
+ // use toFixed() just in case the Number became something like 3.10000001234e-9
201
+ return this.style[PerspectiveTransform.transformStyleName] = style;
202
+ }
203
+
204
+ _setTransformStyleName();
205
+
206
+ app.calc = calc;
207
+ app.update = update;
208
+ app.checkError = checkError;
209
+
210
+ return app;
211
+
212
+
213
+ })();
214
+
215
+
216
+ return PerspectiveTransform;
217
+ });
218
+ }(typeof define === "function" && define.amd ? define : function (app) {
219
+ window["PerspectiveTransform"] = app();
220
+ }));
dat.gui.min.js ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * dat-gui JavaScript Controller Library
3
+ * http://code.google.com/p/dat-gui
4
+ *
5
+ * Copyright 2011 Data Arts Team, Google Creative Lab
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ */
13
+ var dat=dat||{};dat.gui=dat.gui||{};dat.utils=dat.utils||{};dat.controllers=dat.controllers||{};dat.dom=dat.dom||{};dat.color=dat.color||{};dat.utils.css=function(){return{load:function(e,a){var a=a||document,c=a.createElement("link");c.type="text/css";c.rel="stylesheet";c.href=e;a.getElementsByTagName("head")[0].appendChild(c)},inject:function(e,a){var a=a||document,c=document.createElement("style");c.type="text/css";c.innerHTML=e;a.getElementsByTagName("head")[0].appendChild(c)}}}();
14
+ dat.utils.common=function(){var e=Array.prototype.forEach,a=Array.prototype.slice;return{BREAK:{},extend:function(c){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(a[f])||(c[f]=a[f])},this);return c},defaults:function(c){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(c[f])&&(c[f]=a[f])},this);return c},compose:function(){var c=a.call(arguments);return function(){for(var d=a.call(arguments),f=c.length-1;f>=0;f--)d=[c[f].apply(this,d)];return d[0]}},
15
+ each:function(a,d,f){if(e&&a.forEach===e)a.forEach(d,f);else if(a.length===a.length+0)for(var b=0,n=a.length;b<n;b++){if(b in a&&d.call(f,a[b],b)===this.BREAK)break}else for(b in a)if(d.call(f,a[b],b)===this.BREAK)break},defer:function(a){setTimeout(a,0)},toArray:function(c){return c.toArray?c.toArray():a.call(c)},isUndefined:function(a){return a===void 0},isNull:function(a){return a===null},isNaN:function(a){return a!==a},isArray:Array.isArray||function(a){return a.constructor===Array},isObject:function(a){return a===
16
+ Object(a)},isNumber:function(a){return a===a+0},isString:function(a){return a===a+""},isBoolean:function(a){return a===false||a===true},isFunction:function(a){return Object.prototype.toString.call(a)==="[object Function]"}}}();
17
+ dat.controllers.Controller=function(e){var a=function(a,d){this.initialValue=a[d];this.domElement=document.createElement("div");this.object=a;this.property=d;this.__onFinishChange=this.__onChange=void 0};e.extend(a.prototype,{onChange:function(a){this.__onChange=a;return this},onFinishChange:function(a){this.__onFinishChange=a;return this},setValue:function(a){this.object[this.property]=a;this.__onChange&&this.__onChange.call(this,a);this.updateDisplay();return this},getValue:function(){return this.object[this.property]},
18
+ updateDisplay:function(){return this},isModified:function(){return this.initialValue!==this.getValue()}});return a}(dat.utils.common);
19
+ dat.dom.dom=function(e){function a(b){if(b==="0"||e.isUndefined(b))return 0;b=b.match(d);return!e.isNull(b)?parseFloat(b[1]):0}var c={};e.each({HTMLEvents:["change"],MouseEvents:["click","mousemove","mousedown","mouseup","mouseover"],KeyboardEvents:["keydown"]},function(b,a){e.each(b,function(b){c[b]=a})});var d=/(\d+(\.\d+)?)px/,f={makeSelectable:function(b,a){if(!(b===void 0||b.style===void 0))b.onselectstart=a?function(){return false}:function(){},b.style.MozUserSelect=a?"auto":"none",b.style.KhtmlUserSelect=
20
+ a?"auto":"none",b.unselectable=a?"on":"off"},makeFullscreen:function(b,a,d){e.isUndefined(a)&&(a=true);e.isUndefined(d)&&(d=true);b.style.position="absolute";if(a)b.style.left=0,b.style.right=0;if(d)b.style.top=0,b.style.bottom=0},fakeEvent:function(b,a,d,f){var d=d||{},m=c[a];if(!m)throw Error("Event type "+a+" not supported.");var l=document.createEvent(m);switch(m){case "MouseEvents":l.initMouseEvent(a,d.bubbles||false,d.cancelable||true,window,d.clickCount||1,0,0,d.x||d.clientX||0,d.y||d.clientY||
21
+ 0,false,false,false,false,0,null);break;case "KeyboardEvents":m=l.initKeyboardEvent||l.initKeyEvent;e.defaults(d,{cancelable:true,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false,keyCode:void 0,charCode:void 0});m(a,d.bubbles||false,d.cancelable,window,d.ctrlKey,d.altKey,d.shiftKey,d.metaKey,d.keyCode,d.charCode);break;default:l.initEvent(a,d.bubbles||false,d.cancelable||true)}e.defaults(l,f);b.dispatchEvent(l)},bind:function(b,a,d,c){b.addEventListener?b.addEventListener(a,d,c||false):b.attachEvent&&
22
+ b.attachEvent("on"+a,d);return f},unbind:function(b,a,d,c){b.removeEventListener?b.removeEventListener(a,d,c||false):b.detachEvent&&b.detachEvent("on"+a,d);return f},addClass:function(b,a){if(b.className===void 0)b.className=a;else if(b.className!==a){var d=b.className.split(/ +/);if(d.indexOf(a)==-1)d.push(a),b.className=d.join(" ").replace(/^\s+/,"").replace(/\s+$/,"")}return f},removeClass:function(b,a){if(a){if(b.className!==void 0)if(b.className===a)b.removeAttribute("class");else{var d=b.className.split(/ +/),
23
+ c=d.indexOf(a);if(c!=-1)d.splice(c,1),b.className=d.join(" ")}}else b.className=void 0;return f},hasClass:function(a,d){return RegExp("(?:^|\\s+)"+d+"(?:\\s+|$)").test(a.className)||false},getWidth:function(b){b=getComputedStyle(b);return a(b["border-left-width"])+a(b["border-right-width"])+a(b["padding-left"])+a(b["padding-right"])+a(b.width)},getHeight:function(b){b=getComputedStyle(b);return a(b["border-top-width"])+a(b["border-bottom-width"])+a(b["padding-top"])+a(b["padding-bottom"])+a(b.height)},
24
+ getOffset:function(a){var d={left:0,top:0};if(a.offsetParent){do d.left+=a.offsetLeft,d.top+=a.offsetTop;while(a=a.offsetParent)}return d},isActive:function(a){return a===document.activeElement&&(a.type||a.href)}};return f}(dat.utils.common);
25
+ dat.controllers.OptionController=function(e,a,c){var d=function(f,b,e){d.superclass.call(this,f,b);var h=this;this.__select=document.createElement("select");if(c.isArray(e)){var j={};c.each(e,function(a){j[a]=a});e=j}c.each(e,function(a,b){var d=document.createElement("option");d.innerHTML=b;d.setAttribute("value",a);h.__select.appendChild(d)});this.updateDisplay();a.bind(this.__select,"change",function(){h.setValue(this.options[this.selectedIndex].value)});this.domElement.appendChild(this.__select)};
26
+ d.superclass=e;c.extend(d.prototype,e.prototype,{setValue:function(a){a=d.superclass.prototype.setValue.call(this,a);this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue());return a},updateDisplay:function(){this.__select.value=this.getValue();return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common);
27
+ dat.controllers.NumberController=function(e,a){var c=function(d,f,b){c.superclass.call(this,d,f);b=b||{};this.__min=b.min;this.__max=b.max;this.__step=b.step;d=this.__impliedStep=a.isUndefined(this.__step)?this.initialValue==0?1:Math.pow(10,Math.floor(Math.log(this.initialValue)/Math.LN10))/10:this.__step;d=d.toString();this.__precision=d.indexOf(".")>-1?d.length-d.indexOf(".")-1:0};c.superclass=e;a.extend(c.prototype,e.prototype,{setValue:function(a){if(this.__min!==void 0&&a<this.__min)a=this.__min;
28
+ else if(this.__max!==void 0&&a>this.__max)a=this.__max;this.__step!==void 0&&a%this.__step!=0&&(a=Math.round(a/this.__step)*this.__step);return c.superclass.prototype.setValue.call(this,a)},min:function(a){this.__min=a;return this},max:function(a){this.__max=a;return this},step:function(a){this.__step=a;return this}});return c}(dat.controllers.Controller,dat.utils.common);
29
+ dat.controllers.NumberControllerBox=function(e,a,c){var d=function(f,b,e){function h(){var a=parseFloat(l.__input.value);c.isNaN(a)||l.setValue(a)}function j(a){var b=o-a.clientY;l.setValue(l.getValue()+b*l.__impliedStep);o=a.clientY}function m(){a.unbind(window,"mousemove",j);a.unbind(window,"mouseup",m)}this.__truncationSuspended=false;d.superclass.call(this,f,b,e);var l=this,o;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"change",h);
30
+ a.bind(this.__input,"blur",function(){h();l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())});a.bind(this.__input,"mousedown",function(b){a.bind(window,"mousemove",j);a.bind(window,"mouseup",m);o=b.clientY});a.bind(this.__input,"keydown",function(a){if(a.keyCode===13)l.__truncationSuspended=true,this.blur(),l.__truncationSuspended=false});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;c.extend(d.prototype,e.prototype,{updateDisplay:function(){var a=this.__input,
31
+ b;if(this.__truncationSuspended)b=this.getValue();else{b=this.getValue();var c=Math.pow(10,this.__precision);b=Math.round(b*c)/c}a.value=b;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common);
32
+ dat.controllers.NumberControllerSlider=function(e,a,c,d,f){var b=function(d,c,f,e,l){function o(b){b.preventDefault();var d=a.getOffset(g.__background),c=a.getWidth(g.__background);g.setValue(g.__min+(g.__max-g.__min)*((b.clientX-d.left)/(d.left+c-d.left)));return false}function y(){a.unbind(window,"mousemove",o);a.unbind(window,"mouseup",y);g.__onFinishChange&&g.__onFinishChange.call(g,g.getValue())}b.superclass.call(this,d,c,{min:f,max:e,step:l});var g=this;this.__background=document.createElement("div");
33
+ this.__foreground=document.createElement("div");a.bind(this.__background,"mousedown",function(b){a.bind(window,"mousemove",o);a.bind(window,"mouseup",y);o(b)});a.addClass(this.__background,"slider");a.addClass(this.__foreground,"slider-fg");this.updateDisplay();this.__background.appendChild(this.__foreground);this.domElement.appendChild(this.__background)};b.superclass=e;b.useDefaultStyles=function(){c.inject(f)};d.extend(b.prototype,e.prototype,{updateDisplay:function(){this.__foreground.style.width=
34
+ (this.getValue()-this.__min)/(this.__max-this.__min)*100+"%";return b.superclass.prototype.updateDisplay.call(this)}});return b}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,".slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}");
35
+ dat.controllers.FunctionController=function(e,a,c){var d=function(c,b,e){d.superclass.call(this,c,b);var h=this;this.__button=document.createElement("div");this.__button.innerHTML=e===void 0?"Fire":e;a.bind(this.__button,"click",function(a){a.preventDefault();h.fire();return false});a.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};d.superclass=e;c.extend(d.prototype,e.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this);this.__onFinishChange&&this.__onFinishChange.call(this,
36
+ this.getValue());this.getValue().call(this.object)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common);
37
+ dat.controllers.BooleanController=function(e,a,c){var d=function(c,b){d.superclass.call(this,c,b);var e=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");a.bind(this.__checkbox,"change",function(){e.setValue(!e.__prev)},false);this.domElement.appendChild(this.__checkbox);this.updateDisplay()};d.superclass=e;c.extend(d.prototype,e.prototype,{setValue:function(a){a=d.superclass.prototype.setValue.call(this,a);this.__onFinishChange&&
38
+ this.__onFinishChange.call(this,this.getValue());this.__prev=this.getValue();return a},updateDisplay:function(){this.getValue()===true?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=true):this.__checkbox.checked=false;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common);
39
+ dat.color.toString=function(e){return function(a){if(a.a==1||e.isUndefined(a.a)){for(a=a.hex.toString(16);a.length<6;)a="0"+a;return"#"+a}else return"rgba("+Math.round(a.r)+","+Math.round(a.g)+","+Math.round(a.b)+","+a.a+")"}}(dat.utils.common);
40
+ dat.color.interpret=function(e,a){var c,d,f=[{litmus:a.isString,conversions:{THREE_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return a===null?false:{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:e},SIX_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9]{6})$/i);return a===null?false:{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:e},CSS_RGB:{read:function(a){a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
41
+ return a===null?false:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:e},CSS_RGBA:{read:function(a){a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);return a===null?false:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:e}}},{litmus:a.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:a.isArray,conversions:{RGB_ARRAY:{read:function(a){return a.length!=
42
+ 3?false:{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return a.length!=4?false:{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:a.isObject,conversions:{RGBA_OBJ:{read:function(b){return a.isNumber(b.r)&&a.isNumber(b.g)&&a.isNumber(b.b)&&a.isNumber(b.a)?{space:"RGB",r:b.r,g:b.g,b:b.b,a:b.a}:false},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(b){return a.isNumber(b.r)&&
43
+ a.isNumber(b.g)&&a.isNumber(b.b)?{space:"RGB",r:b.r,g:b.g,b:b.b}:false},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)&&a.isNumber(b.a)?{space:"HSV",h:b.h,s:b.s,v:b.v,a:b.a}:false},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)?{space:"HSV",h:b.h,s:b.s,v:b.v}:false},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){d=
44
+ false;var b=arguments.length>1?a.toArray(arguments):arguments[0];a.each(f,function(e){if(e.litmus(b))return a.each(e.conversions,function(e,f){c=e.read(b);if(d===false&&c!==false)return d=c,c.conversionName=f,c.conversion=e,a.BREAK}),a.BREAK});return d}}(dat.color.toString,dat.utils.common);
45
+ dat.GUI=dat.gui.GUI=function(e,a,c,d,f,b,n,h,j,m,l,o,y,g,i){function q(a,b,r,c){if(b[r]===void 0)throw Error("Object "+b+' has no property "'+r+'"');c.color?b=new l(b,r):(b=[b,r].concat(c.factoryArgs),b=d.apply(a,b));if(c.before instanceof f)c.before=c.before.__li;t(a,b);g.addClass(b.domElement,"c");r=document.createElement("span");g.addClass(r,"property-name");r.innerHTML=b.property;var e=document.createElement("div");e.appendChild(r);e.appendChild(b.domElement);c=s(a,e,c.before);g.addClass(c,k.CLASS_CONTROLLER_ROW);
46
+ g.addClass(c,typeof b.getValue());p(a,c,b);a.__controllers.push(b);return b}function s(a,b,d){var c=document.createElement("li");b&&c.appendChild(b);d?a.__ul.insertBefore(c,params.before):a.__ul.appendChild(c);a.onResize();return c}function p(a,d,c){c.__li=d;c.__gui=a;i.extend(c,{options:function(b){if(arguments.length>1)return c.remove(),q(a,c.object,c.property,{before:c.__li.nextElementSibling,factoryArgs:[i.toArray(arguments)]});if(i.isArray(b)||i.isObject(b))return c.remove(),q(a,c.object,c.property,
47
+ {before:c.__li.nextElementSibling,factoryArgs:[b]})},name:function(a){c.__li.firstElementChild.firstElementChild.innerHTML=a;return c},listen:function(){c.__gui.listen(c);return c},remove:function(){c.__gui.remove(c);return c}});if(c instanceof j){var e=new h(c.object,c.property,{min:c.__min,max:c.__max,step:c.__step});i.each(["updateDisplay","onChange","onFinishChange"],function(a){var b=c[a],H=e[a];c[a]=e[a]=function(){var a=Array.prototype.slice.call(arguments);b.apply(c,a);return H.apply(e,a)}});
48
+ g.addClass(d,"has-slider");c.domElement.insertBefore(e.domElement,c.domElement.firstElementChild)}else if(c instanceof h){var f=function(b){return i.isNumber(c.__min)&&i.isNumber(c.__max)?(c.remove(),q(a,c.object,c.property,{before:c.__li.nextElementSibling,factoryArgs:[c.__min,c.__max,c.__step]})):b};c.min=i.compose(f,c.min);c.max=i.compose(f,c.max)}else if(c instanceof b)g.bind(d,"click",function(){g.fakeEvent(c.__checkbox,"click")}),g.bind(c.__checkbox,"click",function(a){a.stopPropagation()});
49
+ else if(c instanceof n)g.bind(d,"click",function(){g.fakeEvent(c.__button,"click")}),g.bind(d,"mouseover",function(){g.addClass(c.__button,"hover")}),g.bind(d,"mouseout",function(){g.removeClass(c.__button,"hover")});else if(c instanceof l)g.addClass(d,"color"),c.updateDisplay=i.compose(function(a){d.style.borderLeftColor=c.__color.toString();return a},c.updateDisplay),c.updateDisplay();c.setValue=i.compose(function(b){a.getRoot().__preset_select&&c.isModified()&&B(a.getRoot(),true);return b},c.setValue)}
50
+ function t(a,b){var c=a.getRoot(),d=c.__rememberedObjects.indexOf(b.object);if(d!=-1){var e=c.__rememberedObjectIndecesToControllers[d];e===void 0&&(e={},c.__rememberedObjectIndecesToControllers[d]=e);e[b.property]=b;if(c.load&&c.load.remembered){c=c.load.remembered;if(c[a.preset])c=c[a.preset];else if(c[w])c=c[w];else return;if(c[d]&&c[d][b.property]!==void 0)d=c[d][b.property],b.initialValue=d,b.setValue(d)}}}function I(a){var b=a.__save_row=document.createElement("li");g.addClass(a.domElement,
51
+ "has-save");a.__ul.insertBefore(b,a.__ul.firstChild);g.addClass(b,"save-row");var c=document.createElement("span");c.innerHTML="&nbsp;";g.addClass(c,"button gears");var d=document.createElement("span");d.innerHTML="Save";g.addClass(d,"button");g.addClass(d,"save");var e=document.createElement("span");e.innerHTML="New";g.addClass(e,"button");g.addClass(e,"save-as");var f=document.createElement("span");f.innerHTML="Revert";g.addClass(f,"button");g.addClass(f,"revert");var m=a.__preset_select=document.createElement("select");
52
+ a.load&&a.load.remembered?i.each(a.load.remembered,function(b,c){C(a,c,c==a.preset)}):C(a,w,false);g.bind(m,"change",function(){for(var b=0;b<a.__preset_select.length;b++)a.__preset_select[b].innerHTML=a.__preset_select[b].value;a.preset=this.value});b.appendChild(m);b.appendChild(c);b.appendChild(d);b.appendChild(e);b.appendChild(f);if(u){var b=document.getElementById("dg-save-locally"),l=document.getElementById("dg-local-explain");b.style.display="block";b=document.getElementById("dg-local-storage");
53
+ localStorage.getItem(document.location.href+".isLocal")==="true"&&b.setAttribute("checked","checked");var o=function(){l.style.display=a.useLocalStorage?"block":"none"};o();g.bind(b,"change",function(){a.useLocalStorage=!a.useLocalStorage;o()})}var h=document.getElementById("dg-new-constructor");g.bind(h,"keydown",function(a){a.metaKey&&(a.which===67||a.keyCode==67)&&x.hide()});g.bind(c,"click",function(){h.innerHTML=JSON.stringify(a.getSaveObject(),void 0,2);x.show();h.focus();h.select()});g.bind(d,
54
+ "click",function(){a.save()});g.bind(e,"click",function(){var b=prompt("Enter a new preset name.");b&&a.saveAs(b)});g.bind(f,"click",function(){a.revert()})}function J(a){function b(f){f.preventDefault();e=f.clientX;g.addClass(a.__closeButton,k.CLASS_DRAG);g.bind(window,"mousemove",c);g.bind(window,"mouseup",d);return false}function c(b){b.preventDefault();a.width+=e-b.clientX;a.onResize();e=b.clientX;return false}function d(){g.removeClass(a.__closeButton,k.CLASS_DRAG);g.unbind(window,"mousemove",
55
+ c);g.unbind(window,"mouseup",d)}a.__resize_handle=document.createElement("div");i.extend(a.__resize_handle.style,{width:"6px",marginLeft:"-3px",height:"200px",cursor:"ew-resize",position:"absolute"});var e;g.bind(a.__resize_handle,"mousedown",b);g.bind(a.__closeButton,"mousedown",b);a.domElement.insertBefore(a.__resize_handle,a.domElement.firstElementChild)}function D(a,b){a.domElement.style.width=b+"px";if(a.__save_row&&a.autoPlace)a.__save_row.style.width=b+"px";if(a.__closeButton)a.__closeButton.style.width=
56
+ b+"px"}function z(a,b){var c={};i.each(a.__rememberedObjects,function(d,e){var f={};i.each(a.__rememberedObjectIndecesToControllers[e],function(a,c){f[c]=b?a.initialValue:a.getValue()});c[e]=f});return c}function C(a,b,c){var d=document.createElement("option");d.innerHTML=b;d.value=b;a.__preset_select.appendChild(d);if(c)a.__preset_select.selectedIndex=a.__preset_select.length-1}function B(a,b){var c=a.__preset_select[a.__preset_select.selectedIndex];c.innerHTML=b?c.value+"*":c.value}function E(a){a.length!=
57
+ 0&&o(function(){E(a)});i.each(a,function(a){a.updateDisplay()})}e.inject(c);var w="Default",u;try{u="localStorage"in window&&window.localStorage!==null}catch(K){u=false}var x,F=true,v,A=false,G=[],k=function(a){function b(){localStorage.setItem(document.location.href+".gui",JSON.stringify(d.getSaveObject()))}function c(){var a=d.getRoot();a.width+=1;i.defer(function(){a.width-=1})}var d=this;this.domElement=document.createElement("div");this.__ul=document.createElement("ul");this.domElement.appendChild(this.__ul);
58
+ g.addClass(this.domElement,"dg");this.__folders={};this.__controllers=[];this.__rememberedObjects=[];this.__rememberedObjectIndecesToControllers=[];this.__listening=[];a=a||{};a=i.defaults(a,{autoPlace:true,width:k.DEFAULT_WIDTH});a=i.defaults(a,{resizable:a.autoPlace,hideable:a.autoPlace});if(i.isUndefined(a.load))a.load={preset:w};else if(a.preset)a.load.preset=a.preset;i.isUndefined(a.parent)&&a.hideable&&G.push(this);a.resizable=i.isUndefined(a.parent)&&a.resizable;if(a.autoPlace&&i.isUndefined(a.scrollable))a.scrollable=
59
+ true;var e=u&&localStorage.getItem(document.location.href+".isLocal")==="true";Object.defineProperties(this,{parent:{get:function(){return a.parent}},scrollable:{get:function(){return a.scrollable}},autoPlace:{get:function(){return a.autoPlace}},preset:{get:function(){return d.parent?d.getRoot().preset:a.load.preset},set:function(b){d.parent?d.getRoot().preset=b:a.load.preset=b;for(b=0;b<this.__preset_select.length;b++)if(this.__preset_select[b].value==this.preset)this.__preset_select.selectedIndex=
60
+ b;d.revert()}},width:{get:function(){return a.width},set:function(b){a.width=b;D(d,b)}},name:{get:function(){return a.name},set:function(b){a.name=b;if(m)m.innerHTML=a.name}},closed:{get:function(){return a.closed},set:function(b){a.closed=b;a.closed?g.addClass(d.__ul,k.CLASS_CLOSED):g.removeClass(d.__ul,k.CLASS_CLOSED);this.onResize();if(d.__closeButton)d.__closeButton.innerHTML=b?k.TEXT_OPEN:k.TEXT_CLOSED}},load:{get:function(){return a.load}},useLocalStorage:{get:function(){return e},set:function(a){u&&
61
+ ((e=a)?g.bind(window,"unload",b):g.unbind(window,"unload",b),localStorage.setItem(document.location.href+".isLocal",a))}}});if(i.isUndefined(a.parent)){a.closed=false;g.addClass(this.domElement,k.CLASS_MAIN);g.makeSelectable(this.domElement,false);if(u&&e){d.useLocalStorage=true;var f=localStorage.getItem(document.location.href+".gui");if(f)a.load=JSON.parse(f)}this.__closeButton=document.createElement("div");this.__closeButton.innerHTML=k.TEXT_CLOSED;g.addClass(this.__closeButton,k.CLASS_CLOSE_BUTTON);
62
+ this.domElement.appendChild(this.__closeButton);g.bind(this.__closeButton,"click",function(){d.closed=!d.closed})}else{if(a.closed===void 0)a.closed=true;var m=document.createTextNode(a.name);g.addClass(m,"controller-name");f=s(d,m);g.addClass(this.__ul,k.CLASS_CLOSED);g.addClass(f,"title");g.bind(f,"click",function(a){a.preventDefault();d.closed=!d.closed;return false});if(!a.closed)this.closed=false}a.autoPlace&&(i.isUndefined(a.parent)&&(F&&(v=document.createElement("div"),g.addClass(v,"dg"),g.addClass(v,
63
+ k.CLASS_AUTO_PLACE_CONTAINER),document.body.appendChild(v),F=false),v.appendChild(this.domElement),g.addClass(this.domElement,k.CLASS_AUTO_PLACE)),this.parent||D(d,a.width));g.bind(window,"resize",function(){d.onResize()});g.bind(this.__ul,"webkitTransitionEnd",function(){d.onResize()});g.bind(this.__ul,"transitionend",function(){d.onResize()});g.bind(this.__ul,"oTransitionEnd",function(){d.onResize()});this.onResize();a.resizable&&J(this);d.getRoot();a.parent||c()};k.toggleHide=function(){A=!A;i.each(G,
64
+ function(a){a.domElement.style.zIndex=A?-999:999;a.domElement.style.opacity=A?0:1})};k.CLASS_AUTO_PLACE="a";k.CLASS_AUTO_PLACE_CONTAINER="ac";k.CLASS_MAIN="main";k.CLASS_CONTROLLER_ROW="cr";k.CLASS_TOO_TALL="taller-than-window";k.CLASS_CLOSED="closed";k.CLASS_CLOSE_BUTTON="close-button";k.CLASS_DRAG="drag";k.DEFAULT_WIDTH=245;k.TEXT_CLOSED="Close Controls";k.TEXT_OPEN="Open Controls";g.bind(window,"keydown",function(a){document.activeElement.type!=="text"&&(a.which===72||a.keyCode==72)&&k.toggleHide()},
65
+ false);i.extend(k.prototype,{add:function(a,b){return q(this,a,b,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(a,b){return q(this,a,b,{color:true})},remove:function(a){this.__ul.removeChild(a.__li);this.__controllers.slice(this.__controllers.indexOf(a),1);var b=this;i.defer(function(){b.onResize()})},destroy:function(){this.autoPlace&&v.removeChild(this.domElement)},addFolder:function(a){if(this.__folders[a]!==void 0)throw Error('You already have a folder in this GUI by the name "'+
66
+ a+'"');var b={name:a,parent:this};b.autoPlace=this.autoPlace;if(this.load&&this.load.folders&&this.load.folders[a])b.closed=this.load.folders[a].closed,b.load=this.load.folders[a];b=new k(b);this.__folders[a]=b;a=s(this,b.domElement);g.addClass(a,"folder");return b},open:function(){this.closed=false},close:function(){this.closed=true},onResize:function(){var a=this.getRoot();if(a.scrollable){var b=g.getOffset(a.__ul).top,c=0;i.each(a.__ul.childNodes,function(b){a.autoPlace&&b===a.__save_row||(c+=
67
+ g.getHeight(b))});window.innerHeight-b-20<c?(g.addClass(a.domElement,k.CLASS_TOO_TALL),a.__ul.style.height=window.innerHeight-b-20+"px"):(g.removeClass(a.domElement,k.CLASS_TOO_TALL),a.__ul.style.height="auto")}a.__resize_handle&&i.defer(function(){a.__resize_handle.style.height=a.__ul.offsetHeight+"px"});if(a.__closeButton)a.__closeButton.style.width=a.width+"px"},remember:function(){if(i.isUndefined(x))x=new y,x.domElement.innerHTML=a;if(this.parent)throw Error("You can only call remember on a top level GUI.");
68
+ var b=this;i.each(Array.prototype.slice.call(arguments),function(a){b.__rememberedObjects.length==0&&I(b);b.__rememberedObjects.indexOf(a)==-1&&b.__rememberedObjects.push(a)});this.autoPlace&&D(this,this.width)},getRoot:function(){for(var a=this;a.parent;)a=a.parent;return a},getSaveObject:function(){var a=this.load;a.closed=this.closed;if(this.__rememberedObjects.length>0){a.preset=this.preset;if(!a.remembered)a.remembered={};a.remembered[this.preset]=z(this)}a.folders={};i.each(this.__folders,function(b,
69
+ c){a.folders[c]=b.getSaveObject()});return a},save:function(){if(!this.load.remembered)this.load.remembered={};this.load.remembered[this.preset]=z(this);B(this,false)},saveAs:function(a){if(!this.load.remembered)this.load.remembered={},this.load.remembered[w]=z(this,true);this.load.remembered[a]=z(this);this.preset=a;C(this,a,true)},revert:function(a){i.each(this.__controllers,function(b){this.getRoot().load.remembered?t(a||this.getRoot(),b):b.setValue(b.initialValue)},this);i.each(this.__folders,
70
+ function(a){a.revert(a)});a||B(this.getRoot(),false)},listen:function(a){var b=this.__listening.length==0;this.__listening.push(a);b&&E(this.__listening)}});return k}(dat.utils.css,'<div id="dg-save" class="dg dialogue">\n\n Here\'s the new load parameter for your <code>GUI</code>\'s constructor:\n\n <textarea id="dg-new-constructor"></textarea>\n\n <div id="dg-save-locally">\n\n <input id="dg-local-storage" type="checkbox"/> Automatically save\n values to <code>localStorage</code> on exit.\n\n <div id="dg-local-explain">The values saved to <code>localStorage</code> will\n override those passed to <code>dat.GUI</code>\'s constructor. This makes it\n easier to work incrementally, but <code>localStorage</code> is fragile,\n and your friends may not see the same values you do.\n \n </div>\n \n </div>\n\n</div>',
71
+ ".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n",
72
+ dat.controllers.factory=function(e,a,c,d,f,b,n){return function(h,j,m,l){var o=h[j];if(n.isArray(m)||n.isObject(m))return new e(h,j,m);if(n.isNumber(o))return n.isNumber(m)&&n.isNumber(l)?new c(h,j,m,l):new a(h,j,{min:m,max:l});if(n.isString(o))return new d(h,j);if(n.isFunction(o))return new f(h,j,"");if(n.isBoolean(o))return new b(h,j)}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(e,a,c){var d=
73
+ function(c,b){function e(){h.setValue(h.__input.value)}d.superclass.call(this,c,b);var h=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"keyup",e);a.bind(this.__input,"change",e);a.bind(this.__input,"blur",function(){h.__onFinishChange&&h.__onFinishChange.call(h,h.getValue())});a.bind(this.__input,"keydown",function(a){a.keyCode===13&&this.blur()});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;c.extend(d.prototype,
74
+ e.prototype,{updateDisplay:function(){if(!a.isActive(this.__input))this.__input.value=this.getValue();return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController,
75
+ dat.controllers.ColorController=function(e,a,c,d,f){function b(a,b,c,d){a.style.background="";f.each(j,function(e){a.style.cssText+="background: "+e+"linear-gradient("+b+", "+c+" 0%, "+d+" 100%); "})}function n(a){a.style.background="";a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";
76
+ a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var h=function(e,l){function o(b){q(b);a.bind(window,"mousemove",q);a.bind(window,
77
+ "mouseup",j)}function j(){a.unbind(window,"mousemove",q);a.unbind(window,"mouseup",j)}function g(){var a=d(this.value);a!==false?(p.__color.__state=a,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function i(){a.unbind(window,"mousemove",s);a.unbind(window,"mouseup",i)}function q(b){b.preventDefault();var c=a.getWidth(p.__saturation_field),d=a.getOffset(p.__saturation_field),e=(b.clientX-d.left+document.body.scrollLeft)/c,b=1-(b.clientY-d.top+document.body.scrollTop)/c;b>1?b=
78
+ 1:b<0&&(b=0);e>1?e=1:e<0&&(e=0);p.__color.v=b;p.__color.s=e;p.setValue(p.__color.toOriginal());return false}function s(b){b.preventDefault();var c=a.getHeight(p.__hue_field),d=a.getOffset(p.__hue_field),b=1-(b.clientY-d.top+document.body.scrollTop)/c;b>1?b=1:b<0&&(b=0);p.__color.h=b*360;p.setValue(p.__color.toOriginal());return false}h.superclass.call(this,e,l);this.__color=new c(this.getValue());this.__temp=new c(0);var p=this;this.domElement=document.createElement("div");a.makeSelectable(this.domElement,
79
+ false);this.__selector=document.createElement("div");this.__selector.className="selector";this.__saturation_field=document.createElement("div");this.__saturation_field.className="saturation-field";this.__field_knob=document.createElement("div");this.__field_knob.className="field-knob";this.__field_knob_border="2px solid ";this.__hue_knob=document.createElement("div");this.__hue_knob.className="hue-knob";this.__hue_field=document.createElement("div");this.__hue_field.className="hue-field";this.__input=
80
+ document.createElement("input");this.__input.type="text";this.__input_textShadow="0 1px 1px ";a.bind(this.__input,"keydown",function(a){a.keyCode===13&&g.call(this)});a.bind(this.__input,"blur",g);a.bind(this.__selector,"mousedown",function(){a.addClass(this,"drag").bind(window,"mouseup",function(){a.removeClass(p.__selector,"drag")})});var t=document.createElement("div");f.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"});
81
+ f.extend(this.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(this.__color.v<0.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});f.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});f.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});f.extend(t.style,
82
+ {width:"100%",height:"100%",background:"none"});b(t,"top","rgba(0,0,0,0)","#000");f.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});n(this.__hue_field);f.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"});a.bind(this.__saturation_field,"mousedown",o);a.bind(this.__field_knob,"mousedown",o);a.bind(this.__hue_field,"mousedown",
83
+ function(b){s(b);a.bind(window,"mousemove",s);a.bind(window,"mouseup",i)});this.__saturation_field.appendChild(t);this.__selector.appendChild(this.__field_knob);this.__selector.appendChild(this.__saturation_field);this.__selector.appendChild(this.__hue_field);this.__hue_field.appendChild(this.__hue_knob);this.domElement.appendChild(this.__input);this.domElement.appendChild(this.__selector);this.updateDisplay()};h.superclass=e;f.extend(h.prototype,e.prototype,{updateDisplay:function(){var a=d(this.getValue());
84
+ if(a!==false){var e=false;f.each(c.COMPONENTS,function(b){if(!f.isUndefined(a[b])&&!f.isUndefined(this.__color.__state[b])&&a[b]!==this.__color.__state[b])return e=true,{}},this);e&&f.extend(this.__color.__state,a)}f.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var h=this.__color.v<0.5||this.__color.s>0.5?255:0,j=255-h;f.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toString(),border:this.__field_knob_border+
85
+ "rgb("+h+","+h+","+h+")"});this.__hue_knob.style.marginTop=(1-this.__color.h/360)*100+"px";this.__temp.s=1;this.__temp.v=1;b(this.__saturation_field,"left","#fff",this.__temp.toString());f.extend(this.__input.style,{backgroundColor:this.__input.value=this.__color.toString(),color:"rgb("+h+","+h+","+h+")",textShadow:this.__input_textShadow+"rgba("+j+","+j+","+j+",.7)"})}});var j=["-moz-","-o-","-webkit-","-ms-",""];return h}(dat.controllers.Controller,dat.dom.dom,dat.color.Color=function(e,a,c,d){function f(a,
86
+ b,c){Object.defineProperty(a,b,{get:function(){if(this.__state.space==="RGB")return this.__state[b];n(this,b,c);return this.__state[b]},set:function(a){if(this.__state.space!=="RGB")n(this,b,c),this.__state.space="RGB";this.__state[b]=a}})}function b(a,b){Object.defineProperty(a,b,{get:function(){if(this.__state.space==="HSV")return this.__state[b];h(this);return this.__state[b]},set:function(a){if(this.__state.space!=="HSV")h(this),this.__state.space="HSV";this.__state[b]=a}})}function n(b,c,e){if(b.__state.space===
87
+ "HEX")b.__state[c]=a.component_from_hex(b.__state.hex,e);else if(b.__state.space==="HSV")d.extend(b.__state,a.hsv_to_rgb(b.__state.h,b.__state.s,b.__state.v));else throw"Corrupted color state";}function h(b){var c=a.rgb_to_hsv(b.r,b.g,b.b);d.extend(b.__state,{s:c.s,v:c.v});if(d.isNaN(c.h)){if(d.isUndefined(b.__state.h))b.__state.h=0}else b.__state.h=c.h}var j=function(){this.__state=e.apply(this,arguments);if(this.__state===false)throw"Failed to interpret color arguments";this.__state.a=this.__state.a||
88
+ 1};j.COMPONENTS="r,g,b,h,s,v,hex,a".split(",");d.extend(j.prototype,{toString:function(){return c(this)},toOriginal:function(){return this.__state.conversion.write(this)}});f(j.prototype,"r",2);f(j.prototype,"g",1);f(j.prototype,"b",0);b(j.prototype,"h");b(j.prototype,"s");b(j.prototype,"v");Object.defineProperty(j.prototype,"a",{get:function(){return this.__state.a},set:function(a){this.__state.a=a}});Object.defineProperty(j.prototype,"hex",{get:function(){if(!this.__state.space!=="HEX")this.__state.hex=
89
+ a.rgb_to_hex(this.r,this.g,this.b);return this.__state.hex},set:function(a){this.__state.space="HEX";this.__state.hex=a}});return j}(dat.color.interpret,dat.color.math=function(){var e;return{hsv_to_rgb:function(a,c,d){var e=a/60-Math.floor(a/60),b=d*(1-c),n=d*(1-e*c),c=d*(1-(1-e)*c),a=[[d,c,b],[n,d,b],[b,d,c],[b,n,d],[c,b,d],[d,b,n]][Math.floor(a/60)%6];return{r:a[0]*255,g:a[1]*255,b:a[2]*255}},rgb_to_hsv:function(a,c,d){var e=Math.min(a,c,d),b=Math.max(a,c,d),e=b-e;if(b==0)return{h:NaN,s:0,v:0};
90
+ a=a==b?(c-d)/e:c==b?2+(d-a)/e:4+(a-c)/e;a/=6;a<0&&(a+=1);return{h:a*360,s:e/b,v:b/255}},rgb_to_hex:function(a,c,d){a=this.hex_with_component(0,2,a);a=this.hex_with_component(a,1,c);return a=this.hex_with_component(a,0,d)},component_from_hex:function(a,c){return a>>c*8&255},hex_with_component:function(a,c,d){return d<<(e=c*8)|a&~(255<<e)}}}(),dat.color.toString,dat.utils.common),dat.color.interpret,dat.utils.common),dat.utils.requestAnimationFrame=function(){return window.webkitRequestAnimationFrame||
91
+ window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout(e,1E3/60)}}(),dat.dom.CenteredDiv=function(e,a){var c=function(){this.backgroundElement=document.createElement("div");a.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear"});e.makeFullscreen(this.backgroundElement);this.backgroundElement.style.position="fixed";this.domElement=
92
+ document.createElement("div");a.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear"});document.body.appendChild(this.backgroundElement);document.body.appendChild(this.domElement);var c=this;e.bind(this.backgroundElement,"click",function(){c.hide()})};c.prototype.show=function(){var c=this;this.backgroundElement.style.display="block";this.domElement.style.display="block";this.domElement.style.opacity=
93
+ 0;this.domElement.style.webkitTransform="scale(1.1)";this.layout();a.defer(function(){c.backgroundElement.style.opacity=1;c.domElement.style.opacity=1;c.domElement.style.webkitTransform="scale(1)"})};c.prototype.hide=function(){var a=this,c=function(){a.domElement.style.display="none";a.backgroundElement.style.display="none";e.unbind(a.domElement,"webkitTransitionEnd",c);e.unbind(a.domElement,"transitionend",c);e.unbind(a.domElement,"oTransitionEnd",c)};e.bind(this.domElement,"webkitTransitionEnd",
94
+ c);e.bind(this.domElement,"transitionend",c);e.bind(this.domElement,"oTransitionEnd",c);this.backgroundElement.style.opacity=0;this.domElement.style.opacity=0;this.domElement.style.webkitTransform="scale(1.1)"};c.prototype.layout=function(){this.domElement.style.left=window.innerWidth/2-e.getWidth(this.domElement)/2+"px";this.domElement.style.top=window.innerHeight/2-e.getHeight(this.domElement)/2+"px"};return c}(dat.dom.dom,dat.utils.common),dat.dom.dom,dat.utils.common);
images/css_globe_bg.jpg ADDED
images/css_globe_diffuse.jpg ADDED
images/css_globe_halo.png ADDED
script.js ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var config = {
2
+ percent: 0,
3
+ lat: 0,
4
+ lng: 0,
5
+ segX: 14,
6
+ segY: 12,
7
+ isHaloVisible: true,
8
+ isPoleVisible: true,
9
+ autoSpin: true,
10
+ zoom: 0,
11
+
12
+ skipPreloaderAnimation: false,
13
+
14
+ goToHongKong: function() {
15
+ goTo(22.28552,114.15769);
16
+ }
17
+ };
18
+
19
+ var stats;
20
+ var imgs;
21
+ var preloader;
22
+ var preloadPercent;
23
+ var globeDoms;
24
+ var vertices;
25
+
26
+ var world;
27
+ var worldBg;
28
+ var globe;
29
+ var globeContainer;
30
+ var globePole;
31
+ var globeHalo;
32
+
33
+ var pixelExpandOffset = 1.5;
34
+ var rX = 0;
35
+ var rY = 0;
36
+ var rZ = 0;
37
+ var sinRX;
38
+ var sinRY;
39
+ var sinRZ;
40
+ var cosRX;
41
+ var cosRY;
42
+ var cosRZ;
43
+ var dragX;
44
+ var dragY;
45
+ var dragLat;
46
+ var dragLng;
47
+
48
+ var isMouseDown = false;
49
+ var isTweening = false;
50
+ var tick = 1;
51
+
52
+ var URLS = {
53
+ bg: 'images/css_globe_bg.jpg',
54
+ diffuse: 'images/css_globe_diffuse.jpg',
55
+ halo: 'images/css_globe_halo.png',
56
+ };
57
+
58
+ var transformStyleName = PerspectiveTransform.transformStyleName;
59
+
60
+ function init(ref) {
61
+
62
+ world = document.querySelector('.world');
63
+ worldBg = document.querySelector('.world-bg');
64
+ worldBg.style.backgroundImage = 'url(' + URLS.bg + ')';
65
+ globe = document.querySelector('.world-globe');
66
+ globeContainer = document.querySelector('.world-globe-doms-container');
67
+ globePole = document.querySelector('.world-globe-pole');
68
+ globeHalo = document.querySelector('.world-globe-halo');
69
+ globeHalo.style.backgroundImage = 'url(' + URLS.halo + ')';
70
+
71
+
72
+ regenerateGlobe();
73
+
74
+ var gui = new dat.GUI();
75
+ gui.add(config, 'lat', -90, 90).listen();
76
+ gui.add(config, 'lng', -180, 180).listen();
77
+ gui.add(config, 'isHaloVisible');
78
+ gui.add(config, 'isPoleVisible');
79
+ gui.add(config, 'autoSpin');
80
+ gui.add(config, 'goToHongKong');
81
+ gui.add(config, 'zoom', 0, 1).listen();
82
+
83
+ stats = new Stats();
84
+ stats.domElement.style.position = 'absolute';
85
+ stats.domElement.style.left = 0;
86
+ stats.domElement.style.top = 0;
87
+ document.body.appendChild( stats.domElement );
88
+
89
+ // events
90
+ world.ondragstart = function () {return false;};
91
+ world.addEventListener('mousedown', onMouseDown);
92
+ world.addEventListener('mousemove', onMouseMove);
93
+ world.addEventListener('mouseup', onMouseUp);
94
+ world.addEventListener('touchstart', touchPass(onMouseDown));
95
+ world.addEventListener('touchmove', touchPass(onMouseMove));
96
+ world.addEventListener('touchend', touchPass(onMouseUp));
97
+
98
+ loop();
99
+ }
100
+
101
+ function touchPass(func) {
102
+ return function(evt) {
103
+ evt.preventDefault();
104
+ func.call(this, {pageX: evt.changedTouches[0].pageX, pageY: evt.changedTouches[0].pageY});
105
+ };
106
+ }
107
+
108
+ function onMouseDown(evt) {
109
+ isMouseDown = true;
110
+ dragX = evt.pageX;
111
+ dragY = evt.pageY;
112
+ dragLat = config.lat;
113
+ dragLng = config.lng;
114
+ }
115
+
116
+ function onMouseMove(evt) {
117
+ if(isMouseDown) {
118
+ var dX = evt.pageX - dragX;
119
+ var dY = evt.pageY - dragY;
120
+ config.lat = clamp(dragLat + dY * 0.5, -90, 90);
121
+ config.lng = clampLng(dragLng - dX * 0.5, -180, 180);
122
+ }
123
+ }
124
+
125
+ function onMouseUp(evt) {
126
+ if(isMouseDown) {
127
+ isMouseDown = false;
128
+ }
129
+ }
130
+
131
+ function regenerateGlobe() {
132
+ var dom, domStyle;
133
+ var x, y;
134
+ globeDoms = [];
135
+ while (dom = globeContainer.firstChild) {
136
+ globeContainer.removeChild(dom);
137
+ }
138
+
139
+ var segX = config.segX;
140
+ var segY = config.segY;
141
+ var diffuseImgBackgroundStyle = 'url(' + URLS.diffuse + ')';
142
+ var segWidth = 1600 / segX | 0;
143
+ var segHeight = 800 / segY | 0;
144
+
145
+ vertices = [];
146
+
147
+ var verticesRow;
148
+ var radius = (536) / 2;
149
+
150
+ var phiStart = 0;
151
+ var phiLength = Math.PI * 2;
152
+
153
+ var thetaStart = 0;
154
+ var thetaLength = Math.PI;
155
+
156
+ for ( y = 0; y <= segY; y ++ ) {
157
+
158
+ verticesRow = [];
159
+
160
+ for ( x = 0; x <= segX; x ++ ) {
161
+
162
+ var u = x / segX;
163
+ var v = 0.05 + y / segY * (1 - 0.1);
164
+
165
+ var vertex = {
166
+ x: - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ),
167
+ y: -radius * Math.cos( thetaStart + v * thetaLength ),
168
+ z: radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ),
169
+ phi: phiStart + u * phiLength,
170
+ theta: thetaStart + v * thetaLength
171
+ };
172
+ verticesRow.push( vertex );
173
+ }
174
+ vertices.push( verticesRow );
175
+ }
176
+
177
+ for ( y = 0; y < segY; ++y ) {
178
+ for ( x = 0; x < segX; ++x ) {
179
+ dom = document.createElement('div');
180
+ domStyle = dom.style;
181
+ domStyle.position = 'absolute';
182
+ domStyle.width = segWidth + 'px';
183
+ domStyle.height = segHeight + 'px';
184
+ domStyle.overflow = 'hidden';
185
+ domStyle[PerspectiveTransform.transformOriginStyleName] = '0 0';
186
+ domStyle.backgroundImage = diffuseImgBackgroundStyle;
187
+ dom.perspectiveTransform = new PerspectiveTransform(dom , segWidth, segHeight);
188
+ dom.topLeft = vertices[ y ][ x ];
189
+ dom.topRight = vertices[ y ][ x + 1];
190
+ dom.bottomLeft = vertices[ y + 1 ][ x ];
191
+ dom.bottomRight = vertices[ y + 1 ][ x + 1 ];
192
+ domStyle.backgroundPosition = (-segWidth * x) + 'px ' + (-segHeight * y) + 'px';
193
+ globeContainer.appendChild(dom);
194
+ globeDoms.push(dom);
195
+ }
196
+ }
197
+
198
+ }
199
+
200
+ function loop() {
201
+ requestAnimationFrame(loop);
202
+ stats.begin();
203
+ render();
204
+ stats.end();
205
+ }
206
+
207
+ function render() {
208
+
209
+ if(config.autoSpin && !isMouseDown && !isTweening) {
210
+ config.lng = clampLng(config.lng - 0.2);
211
+ }
212
+
213
+ rX = config.lat / 180 * Math. PI;
214
+ rY = (clampLng(config.lng) - 270) / 180 * Math. PI;
215
+
216
+ globePole.style.display = config.isPoleVisible ? 'block' : 'none';
217
+ globeHalo.style.display = config.isHaloVisible ? 'block' : 'none';
218
+
219
+ var ratio = Math.pow(config.zoom, 1.5);
220
+ pixelExpandOffset = 1.5 + (ratio) * -1.25;
221
+ ratio = 1 + ratio * 3;
222
+ globe.style[transformStyleName] = 'scale3d(' + ratio + ',' + ratio + ',1)';
223
+ ratio = 1 + Math.pow(config.zoom, 3) * 0.3;
224
+ worldBg.style[transformStyleName] = 'scale3d(' + ratio + ',' + ratio + ',1)';
225
+
226
+ transformGlobe();
227
+ }
228
+
229
+ function clamp(x, min, max) {
230
+ return x < min ? min : x > max ? max : x;
231
+ }
232
+
233
+ function clampLng(lng) {
234
+ return ((lng + 180) % 360) - 180;
235
+ }
236
+
237
+ function transformGlobe() {
238
+
239
+ var dom, perspectiveTransform;
240
+ var x, y, v1, v2, v3, v4, vertex, verticesRow, i, len;
241
+ if(tick ^= 1) {
242
+ sinRY = Math.sin(rY);
243
+ sinRX = Math.sin(-rX);
244
+ sinRZ = Math.sin(rZ);
245
+ cosRY = Math.cos(rY);
246
+ cosRX = Math.cos(-rX);
247
+ cosRZ = Math.cos(rZ);
248
+
249
+ var segX = config.segX;
250
+ var segY = config.segY;
251
+
252
+ for ( y = 0; y <= segY; y ++ ) {
253
+ verticesRow = vertices[y];
254
+ for ( x = 0; x <= segX; x ++ ) {
255
+ rotate(vertex = verticesRow[x], vertex.x, vertex.y, vertex.z);
256
+ }
257
+ }
258
+
259
+ for ( y = 0; y < segY; y ++ ) {
260
+ for ( x = 0; x < segX; x ++ ) {
261
+ dom = globeDoms[x + segX * y];
262
+
263
+ v1 = dom.topLeft;
264
+ v2 = dom.topRight;
265
+ v3 = dom.bottomLeft;
266
+ v4 = dom.bottomRight;
267
+
268
+ expand(v1, v2);
269
+ expand(v2, v3);
270
+ expand(v3, v4);
271
+ expand(v4, v1);
272
+
273
+ perspectiveTransform = dom.perspectiveTransform;
274
+ perspectiveTransform.topLeft.x = v1.tx;
275
+ perspectiveTransform.topLeft.y = v1.ty;
276
+ perspectiveTransform.topRight.x = v2.tx;
277
+ perspectiveTransform.topRight.y = v2.ty;
278
+ perspectiveTransform.bottomLeft.x = v3.tx;
279
+ perspectiveTransform.bottomLeft.y = v3.ty;
280
+ perspectiveTransform.bottomRight.x = v4.tx;
281
+ perspectiveTransform.bottomRight.y = v4.ty;
282
+ perspectiveTransform.hasError = perspectiveTransform.checkError();
283
+
284
+ if(!(perspectiveTransform.hasError = perspectiveTransform.checkError())) {
285
+ perspectiveTransform.calc();
286
+ }
287
+ }
288
+ }
289
+ } else {
290
+ for ( i = 0, len = globeDoms.length; i < len; i ++ ) {
291
+ perspectiveTransform = globeDoms[i].perspectiveTransform;
292
+ if(!perspectiveTransform.hasError) {
293
+ perspectiveTransform.update();
294
+ } else {
295
+ perspectiveTransform.style[transformStyleName] = 'translate3d(-8192px, 0, 0)';
296
+ }
297
+ }
298
+ }
299
+ }
300
+
301
+ function goTo(lat, lng) {
302
+ var dX = lat - config.lat;
303
+ var dY = lng - config.lng;
304
+ var roughDistance = Math.sqrt(dX * dX + dY * dY);
305
+ isTweening = true;
306
+ TweenMax.to(config, roughDistance * 0.01, {lat: lat, lng: lng, ease:'easeInOutSine'});
307
+ TweenMax.to(config, 1, {delay: roughDistance * 0.01, zoom: 1, ease:'easeInOutSine', onComplete: function(){
308
+ isTweening = false;
309
+ }});
310
+ }
311
+
312
+ function rotate(vertex, x, y, z) {
313
+ x0 = x * cosRY - z * sinRY;
314
+ z0 = z * cosRY + x * sinRY;
315
+ y0 = y * cosRX - z0 * sinRX;
316
+ z0 = z0 * cosRX + y * sinRX;
317
+
318
+ var offset = 1 + (z0 / 4000);
319
+ x1 = x0 * cosRZ - y0 * sinRZ;
320
+ y0 = y0 * cosRZ + x0 * sinRZ;
321
+
322
+ vertex.px = x1 * offset;
323
+ vertex.py = y0 * offset;
324
+ }
325
+
326
+ // shameless stole and edited from threejs CanvasRenderer
327
+ function expand( v1, v2 ) {
328
+
329
+ var x = v2.px - v1.px, y = v2.py - v1.py,
330
+ det = x * x + y * y, idet;
331
+
332
+ if ( det === 0 ) {
333
+ v1.tx = v1.px;
334
+ v1.ty = v1.py;
335
+ v2.tx = v2.px;
336
+ v2.ty = v2.py;
337
+ return;
338
+ }
339
+
340
+ idet = pixelExpandOffset / Math.sqrt( det );
341
+
342
+ x *= idet; y *= idet;
343
+
344
+ v2.tx = v2.px + x;
345
+ v2.ty = v2.py + y;
346
+ v1.tx = v1.px - x;
347
+ v1.ty = v1.py - y;
348
+
349
+ }
350
+
351
+ init();
style.css CHANGED
@@ -1,28 +1,86 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
 
 
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
 
 
 
 
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ html, body {
2
+ position: absolute;
3
+ width: 100%;
4
+ height: 100%;
5
+ margin: 0 0;
6
+ overflow: hidden;
7
+ font-family: 'Lato', sans-serif;
8
+ background-color: #000;
9
+ color: #fff;
10
  }
11
 
12
+ .world {
13
+ position: absolute;
14
+ width: 100%;
15
+ height: 100%;
16
+ cursor: pointer;
17
+ cursor: move;
18
+ cursor: -moz-grab;
19
+ cursor: -webkit-grab;
20
+ cursor: grab;
21
  }
22
 
23
+ .world-bg {
24
+ position: absolute;
25
+ width: 100%;
26
+ height: 100%;
27
+ background-position: 50% 50%;
28
+ background-size: cover;
29
  }
30
 
31
+ .world-globe {
32
+ position: absolute;
33
+ left: 50%;
34
+ top: 50%;
35
+ width: 0;
36
+ height: 0;
37
  }
38
 
39
+ .world-globe-pole {
40
+ position: absolute;
41
+ width: 530px;
42
+ height: 530px;
43
+ left: -265px;
44
+ top: -265px;
45
+ border-radius: 50% 50%;
46
+ background-color: #fff;
47
  }
48
+
49
+ .world-globe-doms-container {
50
+ position: absolute;
51
+ left: 50%;
52
+ top: 50%;
53
+ width: 0;
54
+ height: 0;
55
+ }
56
+
57
+ .world-globe-halo {
58
+ position: absolute;
59
+ left: 50%;
60
+ top: 50%;
61
+ width: 730px;
62
+ height: 715px;
63
+ margin-left: -368px;
64
+ margin-top: -350px;
65
+ }
66
+
67
+ .info {
68
+ position: absolute;
69
+ left: 0;
70
+ bottom: 0;
71
+ width: 100%;
72
+ padding: 10px 10px;
73
+ box-sizing: border-box;
74
+ background-color: rgba(0, 0, 0, 0.8);
75
+ color: #fff;
76
+ font-size: 12px;
77
+ }
78
+
79
+ .info-desc {
80
+ color: #ddd;
81
+ font-size: 10px;
82
+ }
83
+
84
+ a {
85
+ color: #ff5f5f;
86
+ }